Skip to content

Services: Support for very basic consumer/service test case - #476

Merged
aomarks merged 4 commits into
servicefrom
service.7
Oct 24, 2022
Merged

Services: Support for very basic consumer/service test case#476
aomarks merged 4 commits into
servicefrom
service.7

Conversation

@aomarks

@aomarks aomarks commented Oct 24, 2022

Copy link
Copy Markdown
Member

Just a start on the service state machine, with a test. Handling for the most basic simple case: one standard consumer that depends on one service. Obviously many cases not yet handled/tested here, but will build out more complexity incrementally.

Also fixes a bug with a missing await, and adds a small test utility method.

Part of #33

@aomarks
aomarks requested a review from justinfagnani October 24, 2022 00:31

@justinfagnani justinfagnani left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

👍

Comment thread src/execution/standard.ts
}

return this._acquireSystemLockIfNeeded(async () => {
return await this._acquireSystemLockIfNeeded(async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is a bit subtle!

Comment thread src/test/util/test-rig-command.ts Outdated
/**
* Return whether this invocation is still running.
*/
get running(): boolean {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What's our style guide say for boolean fields? Should this be isRunning?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It doesn't say anything about that AFAICT (https://google.github.io/styleguide/tsguide.html).

Renamed to isRunning.

Comment thread src/execution/service.ts
id: 'started';
child: ScriptChildProcess;
}
| {id: 'stopping'}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Does this state still have an associated child process?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think it's needed, but if it turns out to be then I will add it. I'm only adding state data as needed.

Comment thread src/execution/service.ts
type: 'info',
detail: 'service-started',
});
this._state = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should the state transition after the promises below settle?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No. The new state is started, and we set up a handler for the "all consumers done" event, which allows the service to shut down.

Comment thread src/execution/service.ts Outdated
this._config,
dependencyFingerprints.value
);
this._state = {id: 'unstarted'};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it's a little confusing to have the state set twice in this case. It's also a bit confusing to see some of these functions be async and use await and others use unawaited promises to set up the next transition... along with the boilerplate of the non-relevant states, I'd maybe in the future consider a state machine library, or some helpers to make the machine even more declarative.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

True. Replaced the async function with the event method style. This does require another state, but it makes sense. (The one other async function was just a mistake, it didn't actually await).

On the boilerplate: as this class grows, a lot more cases end up being meaningful. For now, I like that it forces me to consider every possible state. In some cases there will end up being only one valid state, so that could just be replaced with a simple assert at the top. Keeping it all consistent for now though.

@aomarks
aomarks merged commit 1a1f7b5 into service Oct 24, 2022
@aomarks
aomarks deleted the service.7 branch October 24, 2022 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants