Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Service factory refactor #3382

Merged
merged 32 commits into from
Aug 27, 2019
Merged

Conversation

tomaka
Copy link
Contributor

@tomaka tomaka commented Aug 13, 2019

General overview of the changes:

  • Removes the components.rs module and almost everything that was in it.
  • Adds a ServiceBuilder struct.
  • Removes construct_service_factory!. You are now supposed to define your own functions (eg. new_full and new_light) that create the service using the ServiceBuilder.
  • Adds a lot of generics to Service and adds an AbstractService trait that you are expected to use in practice when you pass the Service around.

I started with very clean and detailed commits, but since I keep getting conflicts with master, and that rebasing is very painful, I rushed the end a bit more. I'd still recommend to review commit by commit.

All commits up to and including Fix the node-cli tests don't break the API. Only the commits afterwards are breaking changes. I would suggest to merge that PR in two parts: up to that commit, then the rest, so that we can revert "the rest" if the refactoring blocks Polkadot. This is because updating Polkadot will not be trivial, and I don't want to take the blame for delaying Kusama because this PR was merged too eagerly. I opened #3384 with the first part separately.

Remains to be done before merging:

- Restore the sync test of node-cli. This test is the one victim of this refactoring, and I need a bit more time figuring out how to restore it.

@tomaka tomaka added the A0-please_review Pull request needs code review. label Aug 13, 2019
@tomaka tomaka requested a review from bkchr August 13, 2019 13:06
Copy link
Contributor

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Low priority suggestion: Given that core/service/src/factory.rs contains the ServiceBuilder logic and given that ServiceBuilder follows the builder pattern and not the factory pattern, how about renaming factory.rs to builder.rs?

@tomaka
Copy link
Contributor Author

tomaka commented Aug 15, 2019

As mentioned in the other PR, I can continue piling up changes, but there's an arbitrary point where I have to stop and submit it.

I agree with the rename, but I also don't really want to continue pushing commits that don't address issues in the PR.

Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

The general structure goes into the right direction, but I don't understand why we have all these new macros. We wanted to get rid of the macro and not introduce multiple new ones.

For the builder, I would like to see a function with_authority_task or a similar name. This should be used by Babe or Aura, so you don't need to check yourself if the current node is an authority.

pub fn start<C>(service: &Service<C>, exit: ::exit_future::Exit, handle: TaskExecutor) where
C: Components,
{
pub fn start(service: &impl AbstractService, exit: ::exit_future::Exit, handle: TaskExecutor) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we not finally remove this function?

@@ -23,7 +23,7 @@ serde_json = "1.0"
client = { package = "substrate-client", path = "../client" }
inherents = { package = "substrate-inherents", path = "../../core/inherents" }
network = { package = "substrate-network", path = "../network" }
service = { package = "substrate-service", path = "../service", optional = true }
service = { package = "substrate-service", path = "../service" }
Copy link
Member

Choose a reason for hiding this comment

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

This import seems to be used only for import TelemetryOnConnect. Isn't that just a stream that tells us when we reconnected to the telemetry? Can we not define this locally?

///
/// Use this macro if you don't actually need the full service, but just the builder in order to
/// be able to perform chain operations.
macro_rules! new_full_start {
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand the reason for this macro. Can we not put all this stuff into a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason why this macro exists is that we don't want to build a full service when for example importing blocks. In order to import blocks, we only need the client, select-chain and import-queue.

I'm using a macro rather than a function because the return type would be very verbose. This is node-template and is supposed to be tweakable for the user, so anything that looks complicated is negative.

Maybe we can introduce a ServiceIntermediaryType trait in the future, or something like that. Since the design needs to be figured out, I'd like to delay that for further refactoring, if that's ok.

/// Backend storage for the client.
type Backend: 'static + client::backend::Backend<Self::Block, Blake2Hasher>;
/// How to execute calls towards the runtime.
type Executor: 'static + client::CallExecutor<Self::Block, Blake2Hasher> + Send + Sync + Clone;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type Executor: 'static + client::CallExecutor<Self::Block, Blake2Hasher> + Send + Sync + Clone;
type CallExecutor: 'static + client::CallExecutor<Self::Block, Blake2Hasher> + Send + Sync + Clone;

Maybe? To not mistake it with future::Executor?

@@ -617,6 +665,80 @@ impl<Components> Executor<Box<dyn Future<Item = (), Error = ()> + Send>>
}
}

impl<T> AbstractService for T
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this impl?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was in order to implement AbstractService on FullComponents and LightComponents. Will remove.

node/cli/src/service.rs Show resolved Hide resolved
node/cli/src/service.rs Show resolved Hide resolved
@tomaka
Copy link
Contributor Author

tomaka commented Aug 19, 2019

I don't understand why we have all these new macros. We wanted to get rid of the macro and not introduce multiple new ones.

If you're talking about the macros in node, one is an unfortunate consequence of the fact that some of the Substrate tests are using the node. Both macros can probably be removed after more future refactoring.

If you're talking about the macros within substrate-service, they are purely internal and similarly I'm going to remove them in the future.

As mentioned, there are tons of changes to make (including the ones you raised in your review), but I didn't want to have a PR that conflicts with half of Substrate.

@bkchr
Copy link
Member

bkchr commented Aug 21, 2019

Can you maybe at least do the basic review comments that do not touch a macro? If you say to all comments "I don't want to push any other commit", I don't see any reason at all why someone should review this 🤷‍♂️
I understand that you want to get this in relative fast, to reduce the number of conflicts. But then please at least address the obvious stuff, like the RA, RtApi generic arguments, the incorrect named file etc. After that we can merge, if we see the final version in the next pr. I also have some ideas and requirements and don't want to make sure I don't miss something across multiple prs.
Otherwise the service stuff will probably calm down after we have Kusama released.

@svyatonik svyatonik mentioned this pull request Aug 26, 2019
3 tasks
In follow-up commits, we want to be able to directly call maintain_transaction_pool, offchain_workers, and start_rpc, without having to implement the Components trait.
This commit is a preliminary step: we extract the code to freestanding functions.
Instead of implementing AbstractService, Future, and Executor on Service, we implement them on NewService instead.

The implementations of AbstractService, Future, and Executor on Service still exist, but they just wrap to the respective implementations for NewService.
Instead of having multiple $build_ parameters passed to the macro, let's group them all into one.

This change is necessary for the follow-up commits, because we are going to call new_impl! only after all the components have already been built.
This makes it possible to be explicit as what the generic parameter of the NewServiceis, without relying on type inference.
Introduces a new builder-like ServiceBuilder struct that creates a NewService.
Similar to the introduction of new_impl!, we extract the actual code into a macro, letting us get rid of the Components and Factory traits
…uilder

Can be used as a replacement for the chain_ops::* methods
Instead of just run, adds run_with_builder to ParseAndPrepareExport/Import/Revert. This lets you run these operations with a ServiceBuilder instead of a ServiceFactory.
This is technically a breaking change, but the transaction-factory crate is only ever used from within substrate-node, which this commit updates as well.
We slightly change the trait bounds in order to make all the methods usable.
@tomaka
Copy link
Contributor Author

tomaka commented Aug 26, 2019

Should be ready for review/merging. I fixed most of the remarks, and would like to delay the ones that aren't trivial to fix in order to get this in sooner.

@bkchr bkchr merged commit d14e727 into paritytech:master Aug 27, 2019
@tomaka tomaka deleted the service-factory-refactor branch August 27, 2019 09:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants