Skip to content
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

Feat/send cut heights #5

Merged
merged 11 commits into from
Jul 17, 2023
Merged

Feat/send cut heights #5

merged 11 commits into from
Jul 17, 2023

Conversation

Takadenoshi
Copy link
Contributor

@Takadenoshi Takadenoshi commented Jun 12, 2023

Implemented a new event heights:

  • this sends an event heights with payload: array of the current cut as seen on chainweb-node max height seen on chainweb-data. Structure: { "data": <numeric height> }

  • Needed to implement better reconnections. The corresponding client PR will use this value to resume with better guarantees of event delivery.

Update: A timely cw-data outage showed that we should not rely on the cw-node cut, so switching to getting the max height seen on cw-data and using that instead.

cw-node cut may be put back in the future if it proves useful.

@Takadenoshi
Copy link
Contributor Author

The original decision to use cw-node heights came after a discussion about the appropriate API to query cw-data's "cut", which there was none. cw-node was used instead, but this already caused issues when querying a cw-stream-server that relied on a stalled cw-data.

I worked around the lack of an API by polling /txs/events?name=coin.TRANSFER?limit=1 which does include coinbase txns and returns txns sorted by height high->low. It is also indexed so it is very performant.

Including coinbase means this can be relied upon to track even idle chains, like testnet04 can be at times.

Some rejected approaches:

/txs/recents does not include coinbase txns

/stats .transactionCount could have been a proxy but it doesn't include coinbase in count either

So we query:

src/sse/chainweb-cut.ts Outdated Show resolved Hide resolved
export default class ChainwebDataHeightTracker {
private _maxHeight: number = -1;
private _running: boolean = false;
private _logger = new Logger('ChainwebDataHeightTracker');
Copy link
Member

Choose a reason for hiding this comment

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

I see you use a custom logger solution. In general we use debug in other packages. Worth considering.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can discuss this further later on but as a note for this decision: I looked for a bit more advanced functionality in a few common packages (including debug) but after not finding something off the shelf that fit my requirements I built a small custom thing over npmlog

The things I was looking for:

  • prefix log line with timestamp (now customizable/optional)
  • prefix log with "section/module" that emitted that log line
  • easily configurable log levels (error/warn/log/debug)

Comment on lines +93 to +105
registerUpdateCallback(fn: NumericCallback) {
validateType(CLASS_NAME, 'registerCallback', fn, 'function');
this._callbacks.add(fn);
}

unregisterUpdateCallback(fn: NumericCallback) {
validateType(CLASS_NAME, 'unregisterCallback', fn, 'function');
if (this._callbacks.has(fn)) {
this._callbacks.delete(fn);
return;
}
this._logger.warn('Unregistering callback: not found; ignoring');
}
Copy link
Member

@alber70g alber70g Jul 10, 2023

Choose a reason for hiding this comment

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

Often, the register callback function also returns a function that can be used to unregister the callback. When dealing with callbacks for specific events, it is beneficial to extend from EventTarget as it handles many cases for Event Emitters.

Note: I see EventTargets' addEventListener doesn't return with an unregister function though 😔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't recall encountering the "register returns unregister" pattern - and we would have to store the unregister callbacks on the other consumer-side of these, so I'm not sure it would be preferable to using the "callback-as-identity" pattern in this specific use case. If we had multiple registrations of the same callback, it would be different.

For now I have opted for explicit register/unregister callback methods, but yes, the register/unregister callbacks can indeed be changed, e.g. these could extend EventEmitter2

Comment on lines 11 to 14
const heightTracker = new ChainwebDataHeightTracker();
heightTracker.start();

const { network, confirmationDepth, heartbeatInterval } = config;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if starting the tracker in the root of the file is best practice. A solution could be to create a singleton getter and do initialisation there.

Comment on lines 2 to 4
import ChainwebEventService from './chainweb-event.js';
import Logger from './logger.js';
import ChainwebCutService from './chainweb-cut.js';
Copy link
Member

Choose a reason for hiding this comment

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

Side note: I see you have a lot of export defaults, it's considered best practice to only export named exports. This improves code readability and refactoring/navigation as the name stays the same across files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll leave this as a TODO as we want to expedite releasing

src/sse/route-service.ts Outdated Show resolved Hide resolved
Copy link
Member

@alber70g alber70g left a comment

Choose a reason for hiding this comment

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

I made various comments on overarching issues/considerations

@Takadenoshi Takadenoshi merged commit ed3deb5 into main Jul 17, 2023
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.

None yet

2 participants