Getting a quicker response from non-query calls

I need to be able to quickly return a response with generated xml for the podcast host I’m writing. It currently takes >30 seconds to respond to each request. Because I’m using @nomeata’s ic-http-bridge solution and aws lambda/gateway has a max 30s timeout, I’m not able to get responses back in time and receive a timeout.

These calls don’t necessarily need to update anything or reach consensus, but I had to make them non-query calls due to what I consider a bug that doesn’t allow query functions to talk to each other across canisters.

I could put my entire app into one canister which would get around that bug and let these functions be query functions, but that’s not good design.

Even so, I will eventually want to make updates when responding to these requests, for example to track which episodes the user has downloaded. But these calls won’t need to reach consensus. Ideally I could quickly return the requested data and kick off a non-query call that can take its time updating everything because no one will be awaiting its completion.

Seems we maybe need something in between a query call and an update call for things that are not mission-critical. Something that returns right away with non-trustworthy data that might not be synced and have consensus with all replicas, but is probably good enough and, most importantly, doesn’t require a 30s waiting period. This could kick off an update call that would eventually get the system into the correct state, but the user wouldn’t need to wait for everyone to reach consensus before displaying what it knows will be the correct response anyway.

Thoughts? Is it possible to let consensus take its time after quickly responding with the data available at the time of the call?

2 Likes

I think it’s a bit unfair to call it a bug; I would call it a limitation of the current design. It’s not straight-forward to support calls from query methods, the security of it now depends on multiple nodes, which increases the damange a malicoius node could do, and then there is the question of what happens when such a query method is called via a replicated call (i.e. an update call or inter-canister call). We expect to offer that feature eventually, but it’s not of the highest priority right now.

Even so, I will eventually want to make updates when responding to these requests, for example to track which episodes the user has downloaded. But these calls won’t need to reach consensus. Ideally I could quickly return the requested data and kick off a non-query call that can take its time updating everything because no one will be awaiting its completion.

Yes, that’s a valid use case, and it could be solved at the level of the proof-of-concept HTTP gateway: Notice that it currently supports an “upgrade to update call”, i.e. the HTTP gateway does a query call, and then the canister tells it “please do it as an update call again.” You could fork the HTTP gateway and then support that the query call response contains some indication “please send this to the user now, but then also call me again via update call so that I can bump a counter etc”.

So I think it’s possible now already!

1 Like

This is a great idea, @nomeata, thanks! I’ll try my hand today at getting that working. Thanks for the suggestion!

1 Like