openwallet-foundation / credo-ts

Typescript framework for building decentralized identity and verifiable credential solutions
https://credo.js.org
Apache License 2.0
257 stars 195 forks source link

Better support for serverless architectures #1212

Open TimoGlastra opened 1 year ago

TimoGlastra commented 1 year ago

One issue we've found when using AFJ in a serverless environment is that it doesn't always work with the serverless model.

Serverless instances are meant to be scaled up and down and work based on request handling. It's easy to start an AFJ instance as part of a serverless architecture, handle requests, etc..

The problem lies mostly in the event system and events that are triggered asynchronously. For external event handlers (event handlers registered by yourself, so you control the implementation m) you could add some hacky way to wait for all events to be finished processing. But that wouldn't work for internal event handlers. Internal event handlers are minimum, but it can cause issues down the line.

I don't think we should fully solve this problem in core, but I do think we can make a few tweaks in core to make userland implementations possible.

A model I've been thinking about is making the event handler an interface. Then, all event handlers that are asynchronous should be updated to return the promise after they handler is completed processing. That's a really small change and could be made really easily.

Then we could make a custom implementation (doesn't have to be a package, can just be in our application), where we keep track off all events being emitted and the handlers being executed. Then, using Async Local Storage in NodeJS (https://nodejs.org/api/async_hooks.html#class-asynclocalstorage, will only work in nodejs) we can track exactly which handlers are being executed for which request to the http serverless server and we can wait to finish the request until the handlers for that specific request have finished processing. Or a new request could be triggered for larger events that will run async

swcurran commented 1 year ago

Interesting stuff -- thanks for putting this down. A quick question. If you have a serverless instance of AFJ deployed, would it be able to support web sockets and return route transport? Or would it be limited to supporting HTTP? If so, for other than the mediator use case, would that limit the usefulness of having a serverless implementation?

TimoGlastra commented 1 year ago

Interesting stuff -- thanks for putting this down. A quick question. If you have a serverless instance of AFJ deployed, would it be able to support web sockets and return route transport? Or would it be limited to supporting HTTP? If so, for other than the mediator use case, would that limit the usefulness of having a serverless implementation?

I think it could. It depends a bit on the serverless infrastructure you're using. However I wouldn't combine the agent with the websocket server for a large deployment I think. You could host a set of mediator agents that can receive messages over http. Then for the sessions with edge wallets you could push the messages to a separate sending service that keeps track of open websocket connections with edge devices. This way you don't have to add more agent instances if you just need more open sockets.