Skip to content

feat: introduce the new BaseServiceV2 class #2210

Merged
smartcontracts merged 3 commits intodevelopfrom
sc/base-service-v2
Mar 8, 2022
Merged

feat: introduce the new BaseServiceV2 class #2210
smartcontracts merged 3 commits intodevelopfrom
sc/base-service-v2

Conversation

@smartcontracts
Copy link
Copy Markdown
Contributor

Description
This PR introduces a new BaseServiceV2 class. BaseServiceV2 is a more advanced version of the original BaseService class with the following key advantages over the original:

  • BaseServiceV2 automatically picks names of environment variables and command-line arguments based on the service's defined options.
  • BaseServiceV2 automatically pulls inputs from the environment, .env files, and command-line arguments as well as the normal options object passed to the service constructor. This means that services based on BaseServiceV2 can be started without an extra boilerplate run.ts file that parses variables.
  • BaseServiceV2 requires that all options come with validators so inputs can be checked before the service starts. No more input validation outside of the service.
  • BaseServiceV2 has built-in looping, removing the need to include looping logic within every long-running service (but still has the option to only run once with loop: false).
  • BaseServiceV2 includes an optional init function that allows services to run once-on-init logic reliably.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 14, 2022

🦋 Changeset detected

Latest commit: 860fef4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@eth-optimism/message-relayer Minor
@eth-optimism/common-ts Patch
@eth-optimism/sdk Patch
@eth-optimism/data-transport-layer Patch
@eth-optimism/replica-healthcheck Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 14, 2022

Codecov Report

Merging #2210 (947783d) into develop (51a527b) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #2210   +/-   ##
========================================
  Coverage    80.08%   80.08%           
========================================
  Files           77       77           
  Lines         2460     2460           
  Branches       450      450           
========================================
  Hits          1970     1970           
  Misses         490      490           
Flag Coverage Δ
contracts 99.29% <ø> (ø)
core-utils 86.77% <ø> (ø)
data-transport-layer 49.72% <ø> (ø)
sdk 55.75% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
packages/sdk/src/interfaces/types.ts 100.00% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 51a527b...947783d. Read the comment docs.


dotenv.config()

const main = async () => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We can entirely cut out this configuration and execution file because the new base service handles all of this for us.

await sleep(this.options.pollingInterval)
protected async main(): Promise<void> {
// If we're already at the tip, then update the latest tip and loop again.
if (this.state.highestCheckedL2Tx > this.state.highestKnownL2Tx) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I reimplemented this to take advantage of the fact that the base service now loops around main() by default, meaning we don't need to do our own looping logic.

}
}

if (require.main === module) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Adding this small piece of boilerplate means the service can be run by directly executing this file.

* @param params.options Options to pass to the service.
* @param params.loops Whether or not the service should loop. Defaults to true.
* @param params.loopIntervalMs Loop interval in milliseconds. Defaults to zero.
*/
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note to self: I'd like a nice way of handling "service containers" -- groups of services that run together. Not sure of the best way to represent this. I'm not particularly happy with the current thing of running a service that runs other services.

@github-actions github-actions bot added the A-pkg-sdk Area: packages/sdk label Feb 16, 2022
@smartcontracts smartcontracts force-pushed the sc/base-service-v2 branch 2 times, most recently from 93fc39e to 38a5944 Compare February 19, 2022 20:37
@smartcontracts smartcontracts marked this pull request as ready for review March 3, 2022 23:50
@smartcontracts smartcontracts force-pushed the sc/base-service-v2 branch 2 times, most recently from cd82e91 to 04e44a4 Compare March 4, 2022 00:24
@github-actions github-actions bot added the A-ops Area: ops label Mar 4, 2022
const program = new Command()
for (const [optionName, optionSpec] of Object.entries(params.optionsSpec)) {
program.addOption(
new Option(`--${optionName.toLowerCase()}`, `${optionSpec.desc}`).env(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

note that this can be done with bcfg to remove a dep

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

@tynes tynes Mar 4, 2022

Choose a reason for hiding this comment

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

I don't think you need to define upfront bcfg which config options there are

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did it with commander mainly so that I could get the --help command by default (you can run ts-node ./path/to/service --help and get useful help info).

Copy link
Copy Markdown
Contributor

@Inphi Inphi left a comment

Choose a reason for hiding this comment

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

LGTM!

public run(): void {
const _run = async () => {
if (this.init) {
this.logger.info('initializing service')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does the logger indicate which service is being initialized? This would be pretty useful info to have.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah the logger includes the name of the service in each log line, so it will be clear which service is being initialized.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 7, 2022

✔️ Deploy Preview for optimism-sdk ready!

🔨 Explore the source changes: 2b36e73

🔍 Inspect the deploy log: https://app.netlify.com/sites/optimism-sdk/deploys/62267ffe81944400086ed6e2

😎 Browse the preview: https://deploy-preview-2210--optimism-sdk.netlify.app

Introduces the new BaseServiceV2 class to eventually replace the older
BaseService class. BaseServiceV2 includes many convenience features like
automatic environment variable and argv parsing.
ProviderLike is too loose because it allows "any" to be ProviderLike.
This tightens the type to only include strings or ethers.Provider
objects.
Rewrites the message-relayer service to use BaseServiceV2. Significantly
reduces the footprint of the message-relayer and enforces stronger input
validation.
@smartcontracts smartcontracts merged commit 61ec2ca into develop Mar 8, 2022
@smartcontracts smartcontracts deleted the sc/base-service-v2 branch March 8, 2022 02:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ops Area: ops A-pkg-sdk Area: packages/sdk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants