-
Notifications
You must be signed in to change notification settings - Fork 30
[ECR-4104] Allow services stopping #1358
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
Conversation
checkNotStopped(); | ||
rootRouter.getRoutes() | ||
.stream() | ||
.filter(r -> r.getPath().equals(mountPoint)) |
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.
looks like it should work well because service paths are unique within the network by design
*/ | ||
void mountSubRouter(String mountPoint, Router subRouter); | ||
|
||
void removeSubRouter(String mountPoint); |
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.
Specification.
activateService(instanceSpec); | ||
} else if (instanceStatus.equals(Status.STOPPED)) { | ||
stopService(instanceSpec); | ||
} else if (instanceStatus.equals(Status.NONE)) { |
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.
What's the point of notifying of NONE status? What does it mean?
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.
None status means that the service is added but not active yet. Such could happen when restoring instances state.
See: exonum/src/runtime/dispatcher/mod.rs:263
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.
Runtime#update_service_status does not have NONE
status. It accepts a
status: InstanceStatus
which is either active or stopped (at our revision):
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.
Also it could have a None rust type. See the mapping to protobuf msg: https://github.com/exonum/exonum/blob/3c5bf23c090c6a6cc8ae184ce18f1cab34ac2fc0/exonum/src/runtime/types.rs#L461
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.
Runtime#update_service_status cannot receive NONE
as InstanceStatus, so it's not the case. AFAIK NONE
is only used by internal dispatcher logic as a temporary value.
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.
There is no Option in the Runtime#update_service_status API.
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.
You are right, got it. Dispatcher will panic in case of Node during restore.
} else if (instanceStatus.equals(Status.STOPPED)) { | ||
stopService(instanceSpec); | ||
} else if (instanceStatus.equals(Status.NONE)) { | ||
logger.warn("None status for the service instance {}, ignore. " |
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.
log at info? Also, I am not sure if such questions shall appear in the log (it would be nice if we — as SR developers — do know for sure):
"Possibly restoring services state after reboot?"
What does Runtime spec say?
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.
Core Dispatcher invokes updateInstanceStatus for each service in the schema regardless of the status. Not sure why do we restore not active services?
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.
Re none — see the reply above; re stopped — are you saying the core confuses a "request to stop a service instance" with a "notification that a service instance has been stopped already"? Why is that?
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.
are you saying the core confuses a "request to stop a service instance" with a "notification that a service instance has been stopped already"? Why is that?
@bullet-tooth Have you managed to clarify that? Shall the statuses in core be improved to avoid decoding of what 'stopped' means in each runtime?
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.
Created a ticket https://jira.bf.local/browse/ECR-4128
|
||
private ServiceWrapper createService(ServiceInstanceSpec instanceSpec) { | ||
private void stopService(ServiceInstanceSpec instanceSpec) { | ||
// TODO: ECR-2334 add restriction for creation new snapshots |
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.
private void stopService(ServiceInstanceSpec instanceSpec) { | ||
// TODO: ECR-2334 add restriction for creation new snapshots | ||
String name = instanceSpec.getName(); | ||
Optional<ServiceWrapper> activeService = findService(name); |
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.
Why does this code perform a no-op when stopping of a non-existent service
is requested? Shan't it just throw? In this case, a simpler
int id = instanceSpec.getId();
ServiceWrapper service = getServiceById(id); // Will throw if does not exist.
will do.
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 will have non-existent service in case of restoring state
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.
Interesting — I'd consider if any changes to how core works are needed, if we don't miss anything: #1358 (comment)
|
||
server.mountSubRouter(path, server.createRouter()); | ||
Assertions.assertThat(server.getMountedRoutes()) | ||
.anyMatch(route -> routPathEquals(route, path)); |
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.
route
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = {"/foo", "/foo/", "/foo/bar", "/foo/:bar", "/foo/:bar/"}) |
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.
Are ":bar" 📊 request params?
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.
Yes, it's request param.
* Activation leads to the service instance registration, allowing subsequent operations on it: | ||
* transactions, API requests. | ||
* Stopping leads to the service disabling i.e. stopped service does not execute transactions, | ||
* process events, provide APIs, etc. And it becomes unavailable to other services, |
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.
The latest sentence is rather unclear. What becomes unavailable? I thought database indexes are still available after service stopping. Service interface methods (i.e. transactions) becomes unavailable, but we do not have support for them in EJB.
Also, ECR-4119. |
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.
The code looks good, but I suggest to clarify the question on the stopped status (#1358 (comment)).
if (instanceStatus.equals(Status.ACTIVE)) { | ||
activateService(instanceSpec); | ||
} else if (instanceStatus.equals(Status.STOPPED)) { | ||
stopService(instanceSpec); | ||
} else { | ||
String msg = String.format("Unexpected status %s received for the service %s", | ||
instanceStatus.name(), instanceSpec.getName()); | ||
logger.error(msg); | ||
throw new IllegalArgumentException(msg); | ||
} |
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'd suggest a switch:
switch (instanceStatus) {
case ACTIVE:
activateService(instanceSpec);
break;
case STOPPED:
stopService(instanceSpec);
break;
default:
String msg = String.format("Unexpected status %s received for the service %s",
instanceStatus.name(), instanceSpec.getName());
logger.error(msg);
throw new IllegalArgumentException(msg);
}
I think we may integrate it now and adjust after ECR-4128. However, the build is red. |
green :) |
Overview
See: https://jira.bf.local/browse/ECR-4104
Definition of Done