-
Notifications
You must be signed in to change notification settings - Fork 978
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
Persistent subgraphs #513
Persistent subgraphs #513
Conversation
Opening this up for code review now since there's a lot here, despite the fact that it's not done. Most of the work from the last few days has been trying to remove the assumption that each subgraph has one and only one name... would be interested in some feedback on whether that's the right approach. @Jannis Update: done now! |
ce01583
to
4141d40
Compare
In an architecture with a dedicated name service the node would not be managing names at all, but we still want built-in name management for standalone nodes. To make this mode switching easier, what do you think of extracting the name logic in |
Ah interesting. That could work. What would this look like externally? Right now I believe the JSON RPC service has deploy/remove/authorize/list. Should we use the existing verbs, revise them to make them more flexible, or add a separate JSON RPC service with a new set? |
@timmclean I wouldn't touch that layer at all yet, we're gonna need to figure that out later (hopefully it will be graphql mutations rather than json-rpc) but for now I just wanna make sure it will be clean and easy to turn off the code that writes and removes names. |
So how would |
Planned refactor for separating name functionality from SubgraphProvider:
@leodasvacas |
@timmclean thanks for writing out the plan, looks solid! |
Refactor done! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is great! Left some comments.
@leodasvacas I pushed some commits, how does this look? |
b8b918d
to
a99c3c3
Compare
Latest commit adds separate endpoints to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the new url scheme!
service.handle_not_found() | ||
}, | ||
), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now print urls on deploy but I guess it's still nice to have this back. Could you also bring back the comment that explains what this does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh true, yeah, I don't feel too strongly on having a redirect or not! I was tempted to put in a quicky plaintext list of subgraph names...
Comment added though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! A few small comments, some just notes, a couple changes I'd like to see.
core/src/subgraph/provider.rs
Outdated
.event_sink | ||
.clone() | ||
.send(SubgraphProviderEvent::SubgraphStop(id)) | ||
.map_err(|e| panic!("failed to forward subgraph removal: {}", e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is removal
still the best word here?
logger.clone(), | ||
Arc::new(subgraph_provider), | ||
store.clone(), | ||
).wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wait
... can it not cause freezing (e.g. if something inside init
were to spawn something)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my current level of tokio understanding, I think it's fine... async_main is already running inside the context of a tokio runtime, and tokio can use other threads
@leodasvacas ?
server/http/src/service.rs
Outdated
.header( | ||
header::LOCATION, | ||
header::HeaderValue::from_str(destination) | ||
.expect("invalid redirect destination"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something that should make the node panic?
server/json-rpc/src/lib.rs
Outdated
|
||
return Err(json_rpc_error( | ||
JSON_RPC_UNAUTHORIZED_ERROR, | ||
"API key is invalid".to_owned(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be Invalid access token
, since API key
is not what we call this any more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense!
server/json-rpc/src/lib.rs
Outdated
@@ -160,36 +196,62 @@ impl<T: SubgraphProvider> JsonRpcServer<T> { | |||
) -> Result<Value, jsonrpc_core::Error> { | |||
info!(self.logger, "Received subgraph_authorize request"; "params" => params.to_string()); | |||
Self::require_master_token(auth)?; | |||
*self.subgraph_api_keys.write().unwrap() = params.subgraph_api_keys; | |||
|
|||
for (subgraph_name, access_token) in params.subgraph_api_keys { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's rename subgraph_api_keys
to subgraph_access_tokens
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change in the JSON-RPC API but that's fine IMHO.
@@ -434,6 +434,104 @@ impl Store { | |||
} | |||
|
|||
impl StoreTrait for Store { | |||
fn authorize_subgraph_name(&self, name: String, new_access_token: String) -> Result<(), Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're putting a bit much into the Store
. At some point it will be worth thinking about splitting this up into separate traits and separate implementations. But not right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. We should have a separate store component for subgraph name info
store/postgres/src/store.rs
Outdated
None => { | ||
debug!( | ||
self.logger, | ||
"Subgraph name {:?} has no associated access token. Access denied by default.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should use structured logging:
debug!(
self.logger,
"Subgraph has no associated access token. Access denied by default.";
"subgraph_name" => &subgraph_name
);
Also: you're passing in access_token
instead of subgraph_name
anyway. 😉
… subgraph name and ID
More work to remove the assumption that each subgraph ID is associated with a single name.
…ption of 1 name per subgraph
based on code review feedback
…usion in URLs Adds pages at /by-id/<subgraph ID> and /by-name/<subgraph name>
6f6e07a
to
15f6f2b
Compare
I think I got everything! |
I believe with this PR we can leave
ethsf
behind?Resolves #404
Major changes:
Store
has 7 new methods related to reading/writing/deleting subgraph name->ID mappings, access tokens, etc. This information was previously stored in-memory in graph-node.Arc<Store>
and have been rewritten to use that (e.g. JSON RPC service, SubgraphProvider deploy/remove)SubgraphProvider::new
is nowSubgraphProvider::init
. It retrieves a list of subgraph names from the Store and starts those subgraphs.MockStore
has been extended with mock implementations for some of the new methods.MockStore
is used in a bunch of new places now that more components use a Store.SubgraphProvider
deploy
andremove
are hopefully pretty readable.deploy
is essentially:SubgraphProvider::remove
to undeploy the subgraph name if it already existsremove
is essentially: