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: remove MessagePickupRepository injection symbol #2168

Conversation

genaris
Copy link
Contributor

@genaris genaris commented Jan 31, 2025

This PR removes MessagePickupRepository injection symbol, which makes DIDComm base module to not depend on Message Pickup. Instead, MessageSender emits an internal event when a message is meant to be queued for pickup (e.g. when the recipient does have a transport queue endpoint). Such event is catched by MessagePickupModule and effectively added to the queue there.

The main advantage for now (apart from removing an InjectionSymbol) is that we can define a very basic DIDComm Agent that only includes the very basic DIDComm modules (didcomm, oob and connections).

I want to take this as an initial step to refactor the relationship between modules within DIDComm. For instance, I think it would be nice to put in MessagePickupModule the logic for pickup clients that currently resides on MediationRecipientApi, and maybe we can even reduce the amount of modules by having a single mediation module that will be used for the Mediation Coordination protocol, leaving the base mediation features (records, Forward message handling) to the base DIDComm module, along with connections/oob.

Signed-off-by: Ariel Gentile <gentilester@gmail.com>
@genaris genaris requested a review from a team as a code owner January 31, 2025 00:05
Copy link

changeset-bot bot commented Jan 31, 2025

⚠️ No Changeset found

Latest commit: 9e9c901

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

Copy link
Contributor

@TimoGlastra TimoGlastra left a comment

Choose a reason for hiding this comment

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

Nice! only one bigger concern re the events and serverless architectures.

Otherwise, would be really interested to also think more about the multi-instance session management. We're now discussing it in mediator repo (not sure what came out of the WG call yesterday?), but it's probably relevant to solve in Credo core (at least provide the needed interfaces).


// This is an internal event that will be catched by Message Pickup module and queued, in case the
// Agent supports it
this.emitQueuePackedMessageForPickupEvent(agentContext, {
Copy link
Contributor

Choose a reason for hiding this comment

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

I generally like this new approach, but one downside is that if no message pickup module is registered the queued messages will be lost. I think if we receive a message that can't be delivered we should probably handle that in some way(maybe we can check if there's any subscribers?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, one more consideration is that we've noticed that in serverless architectures asynchronous events don't really work well. You don't know when an incoming request is done processing.

That's why I wanted to look into reducing the number of events emitted, but I wasn't sure yet what a good approach would be. I think callbacks make sense, but is also what we had previously (we could of course have no handler by default, and the message pickup module can register it, but then we're basically back at the injection in a different way).

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Say you don't like this approach without saying you don't like this approach! 😆

Seriously speaking, I think we can solve this problem in different ways, and surely we can avoid using async events for that. If we leave this "Queue Transport repository" as a core feature of DIDComm, we can queue messages synchronously. Also, if we consider mediation (the concept itself, not the coordination protocols) as a core feature, we can also setup there different queue transport policies, like the one you mentioned some time ago about only queuing messages for agents we are a mediator of.

Copy link
Contributor

Choose a reason for hiding this comment

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

Say you don't like this approach without saying you don't like this approach! 😆

I really like getting rid of the injection symbols :)

But i've also had some bad experience trying to make credo work in serverless environments and it sadly just didn't work :(

public constructor(options: MessagePickupModuleConfigOptions<MessagePickupProtocols>) {
this.options = options
// Message Pickup queue: use provided one or in-memory one if no injection symbol is yet defined
this.#messagePickupRepository = options.messagePickupRepository ?? new InMemoryMessagePickupRepository()
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we change this to something like messageQueueRepository? or queuedMessageRepository?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This subtle question made me think that the approach we are following is not correct: this message queue is part of DIDComm core, regardless of the message pickup mechanism we use (for instance, the infamous "implicit" mode present in some mediators do not use Message Pickup protocol at all, but they do access this element to send queued messages to their clients at the moment they connect to a WebSocket).

In such case, this QueueTransportMessageRepository must be defined in the base DIDComm module configuration, and therefore much of the things done in this PR would not make sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. Routing/forwarding/queuing is part of core. Mediator management and pickup not! :)

private messages: InMemoryQueuedMessage[]

public constructor(@inject(InjectionSymbols.Logger) logger: Logger) {
public constructor(@inject(InjectionSymbols.Logger) logger?: Logger) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why optional?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't have access to this, we should just pass the agent context to all the methods in this class I think

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I didn't want to change all MessagePickupRepository interface methods only for this basic implementation. But I think resistance is futile: a good refactoring of all of this will be needed before 0.6.0 release!

@TimoGlastra
Copy link
Contributor

Can you add changeset(s) for the changes?

@genaris
Copy link
Contributor Author

genaris commented Feb 1, 2025

For the moment I'll close this PR in favour of another one where we can refactor DIDComm modules in such a way that core features and concepts are part of the base module, and we leave protocol-specific parts to the corresponding modules.

@genaris genaris closed this Feb 1, 2025
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