Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add list of services to enable (ECR-1766) & bundle btc-anchoring (ECR-1366) #338

Merged
merged 17 commits into from
Jul 7, 2018

Conversation

vitvakatu
Copy link
Contributor

@vitvakatu vitvakatu commented Jul 4, 2018

Overview

Added list of services to enable in a separate TOML file.
Now it supports two services - configuration and anchoring.


See: https://jira.bf.local/browse/ECR-1766
See: https://jira.bf.local/browse/ECR-1366

Definition of Done

@vitvakatu vitvakatu self-assigned this Jul 4, 2018
Copy link
Contributor

@dmitry-timofeev dmitry-timofeev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, I'd add some tests.

let mut builder =
fabric::NodeBuilder::new().with_service(Box::new(java_bindings::JavaServiceFactory));
for service in &services.services {
if service == CONFIGURATION_SERVICE {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a map of system service factories (name -> factory)? Then we can get rid of this chain of if/else if/…/else, which will grow a little:

for service_name in service_to_enable:
  if (system_services.contains(service_name)):
    builder = builder.with_service(system_services.get(service_name));
  else:
    panic("unknown service: " + service_name);

You can even put there a java service factory, and append its name to the list of service-to-enable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, will try

use java_bindings::exonum::helpers::fabric;

const PATH_TO_SERVICES_TO_ENABLE: &str = "ejb_app_services.toml";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected to be in the current working directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

@@ -0,0 +1 @@
services = ["configuration"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this file is checked in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because configuration service should be enabled by default. I can remove this file though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if that's the case it shall work reliably with empty or no file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh well... 🤔
Indeed, we don't need this file.

);
service_factories.insert(
BTC_ANCHORING_SERVICE.to_owned(),
Box::new(BtcAnchoringServiceFactory) as Box<ServiceFactory>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK to instantiate the factories here (instead of providing a factory method for a factory — a method reference)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's okay


let mut builder = fabric::NodeBuilder::new();
for service_name in &services {
match service_factories.remove(service_name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think of this map of factories as an immutable map, but see it's not the case. I also see a new one is created when service_factories is called, so it’s OK in terms of correctness to remove the factories from it. This process looks a little complicated. Is there a good reason to not use an immutable map?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immutable map will give only references to values to me which is not enough - I need owned values. Well, technically, we can use closures stored in HashMap. Will try and look at complexity.
To be honest, the current solution is much more complicated then first attempt with simple if...else

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, the current solution is much more complicated

Yes, it is more complex. Rust complicated things :-) If/else is repetitive and error prone (you have to test each branch basically), but if a solution with a map results in complex Rust code, we can go back to it.

services: HashSet<String>,
}

fn service_factories() -> HashMap<String, Box<ServiceFactory + 'static>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't Box<ServiceFactory> 'static by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be, but compiler doesn't think so 🙃

@vitvakatu
Copy link
Contributor Author

@dmitry-timofeev I tried several approaches. The current one is the most simple and effective one. Additionally, it's just a temporary solution for our problems.

@vitvakatu
Copy link
Contributor Author

@alexander-irbis oh lol. Just tried to remove 'static bound and it works! Don't know why I had compilation error before

@dmitry-timofeev
Copy link
Contributor

@dmitry-timofeev I tried several approaches. The current one is the most simple and effective one.

Looks good, please add tests.


#[test]
fn broken_config() {
let cfg = create_config("broken.toml", "not_list = 1");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shan't we throw in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... No, be just use default config... I'll consider panicing

export LD_LIBRARY_PATH="$(find ${JAVA_HOME} -type f -name libjvm.* | xargs -n1 dirname)"
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"

# Compile all Java modules by default to ensure that ejb-fakes module, which is required
Copy link
Contributor

@dmitry-timofeev dmitry-timofeev Jul 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why, do app tests depend on any Java classes?

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Runs EJB App tests (ejb-core/rust/ejb-app).
Copy link
Contributor

@dmitry-timofeev dmitry-timofeev Jul 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we call run_ejb_app_tests.sh from run_all_tests.sh run_native_integration_tests.sh?

Edit: I see, we do call from run_all_tests. Does it belong there or in native_its?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's just separated tests, not native_its

});
use std::fs::File;
use std::io::Read;
let mut services = if let Ok(mut file) = File::open(path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider adding a comment to express the intent.

@dmitry-timofeev dmitry-timofeev added the Next to merge 🛬 The next PR to merge (that is up-to-date with master) label Jul 6, 2018
fn broken_config() {
let cfg = create_config("broken.toml", "not_list = 1");
let services_to_enable = services_to_enable(cfg);
assert_eq!(services_to_enable.len(), 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps there is no need in asserts?

@@ -118,9 +118,6 @@ mod tests {
fn broken_config() {
let cfg = create_config("broken.toml", "not_list = 1");
let services_to_enable = services_to_enable(cfg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable seems to break clippy (shall it be prefixed with an underscore?).

@dmitry-timofeev dmitry-timofeev merged commit 5af6dca into exonum:master Jul 7, 2018
@dmitry-timofeev
Copy link
Contributor

@vitvakatu , would you please update the instructions in TUTORIAL.md, as a separate task?

@vitvakatu vitvakatu deleted the ECR-1766 branch July 7, 2018 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Next to merge 🛬 The next PR to merge (that is up-to-date with master)
Development

Successfully merging this pull request may close these issues.

3 participants