-
Notifications
You must be signed in to change notification settings - Fork 92
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
Checkpoint chaincode event listening #362
Comments
Integrated vs wrapper implementationA checkpointing solution tightly integrated into the existing event delivery turned out not to be practical, mainly due to the off-line signing flow. This serialises only the protobuf messages and loses and more transient information, such as a selected checkpointer, leaving no way to automatically recreate this when the request (along with signature) is reconstructed after the off-line signing takes place. The approach currently favoured is a wrapper around the event iterator or channel. Automatic checkpoint of eventsThe pull model used for event delivery (iterator / channel) provides good control of rate of message delivery and easier management of the eventing session but it means that the client API has no way of knowing whether a supplied event is successfully processed by the client application or whether a processing error occurs. The push model used in the legacy SDKs (observer pattern) returns control to the client API after the application event consumer function is invoked, so a non-error return can be safely assumed to mean the event was successfully processed. One approach to allow events to be automatically checkpointed by the API would be to provide a push (observer pattern) API for event delivery when checkpointing is used, similar to the legacy SDKs and built on top of the pull (iterator / channel) API. This would allow automatic checkpointing but is a lot of additional complexity and API surface to support. The alternative currently favoured is to require an explicit checkpoint call by the client application on successful event processing. |
To allow resume of eventing with no missed or duplicate events, the checkpointing implementation needs to address two concerns:
The ChaincodeEvents service already guarantees that events are delivered ordered by block number and position of the emitting transaction within the block so, during an event listening session, no events will be missed or duplicated. Filtering out previously processed events at the client end presents different challenges depending on the implementation language. A better approach is to prevent the client from receiving previously processed events by adding an optional Extending the ChaincodeEventsRequest protobuf message has the added advantage of retaining the The Checkpointer interface/implementation is only required to store the current block number and, if any transactions within that block have been processed, the last successfully processed transaction ID. There is no need to store all previously processed transaction IDs within a block. So the Checkpointer interface can become: interface Checkpointer {
checkpoint(blockNumber: bigint, transactionId?: string): Promise<void>;
getBlockNumber(): bigint | undefined;
getTransactionId(): string | undefined;
} Record last processed eventThe
I suggest we start with the first option, as it requires little or no additional implementation in the client API and is still trivial for the client application to use. Specify last processed event on resumeThe client application must specify both the start block and (if one exists) last successfully processed transaction ID when resuming eventing after a transient connection failure or in a subsequent application run. Implementation options include:
The second option is slightly less work for the client application and no extra work in the client API implementation, so I think I would favour that approach. |
As an application developer
I want checkpoint capability for chaincode events
So that I can resume event listening following a connection error or application restart with minimal application code
Using checkpointing, event listening should resume after the last successfully processed event. No events should be missed and no duplicate events should be delivered.
Options for dealing with connection errors are to either:
For simplicity and to avoid obscuring persistent connection failures, the second approach might be preferred.
It might be possible to implement checkpointing as purely a wrapper API around the existing (non-checkpointing) event listening API. The advantage to this approach would be simplicity of the core eventing implementation. The disadvantage would be that the checkpoint implementation could not take advantage of information available only within the eventing implementation, such as visibility of the number of events contained within a given block.
The text was updated successfully, but these errors were encountered: