appwrite / appwrite

Your backend, minus the hassle.
https://appwrite.io
BSD 3-Clause "New" or "Revised" License
44.93k stars 3.99k forks source link

🐛 Bug Report: Async Function Execution Response Body Empty #6256

Closed noob8boi closed 8 months ago

noob8boi commented 1 year ago

👟 Reproduction steps

1) Create an async execution [Flutter SDK]. 2) Try getExecution() in a loop till you don't get completed / failed status for the current execution. 3) Check the responseBody field.

👍 Expected behavior

It should have the the proper body in JSON string format.

👎 Actual Behavior

I just get null / empty value in responseBody.

🎲 Appwrite version

Version 1.4.x

💻 Operating system

Linux

🧱 Your Environment

Appwrite 1.4.2 appwrite 11.0.0 [flutter-sdk]

👀 Have you spent some time to check if this issue has been raised before?

🏢 Have you read the Code of Conduct?

stnguyen90 commented 1 year ago

@noob8boi, thanks for raising this issue! 🙏🏼 As of 1.4, this is the expected behavior. This was done to lift the limit of 1MB response. You'll need to store the data somewhere and fetch it there.

gandhimaulik commented 10 months ago

So nothing planned for this going forward? It is pain to debug this after upgrade from 1.2 to 1.4, all things breaking.

You'll need to store the data somewhere and fetch it there.

Totally unnecessary to be implemented by each user of appwrite.

Even if you could put limit that. async function will not support (truncate) response over 1MB, that would be better. Majority of users would not require storing response and querying manually and multiple request over network.

amalik99 commented 9 months ago

Any ETA on this?

t0mm4rx commented 8 months ago

I think this should be included somewhere in the doc. This is really hard to debug as it silently fails.

What is the intended use of async functions if you cannot get their response? Shouldn't it be removed to avoid confusion?

Also now that we cannot execute sync functions longer than 30s due to Traefik, it may be useful to have a solution for long-running functions that returns something to the user.

stnguyen90 commented 8 months ago

For debugging, you can use the log method in the context and then check the logs. See https://appwrite.io/docs/products/functions/execution#logs

Closing as this is the expected behavior.

barart commented 6 months ago

This is annoying, my function takes around 5-11 secs to run, but, sometimes if server is busy it takes more than 30 secs, using sync functions to retrieve responsebody (i need values that my function returns) is what i need, but if server is busy and it takes more than 30 secs, it timeout and my project ends in a mess of data that i need manually clean... ok, lets do it on async but i cant retrieve responsebody, so now, i need to write something else to write function results and retrieve it when it completes or to clean data if it fails and re-run again... is a waste of resources and time, more if function is executed multiple times at the same time by multiple users...

We need the responsebody on async or decide us to manage our sync timeouts.. simple like that

barart commented 6 months ago

For debugging, you can use the log method in the context and then check the logs. See https://appwrite.io/docs/products/functions/execution#logs

Closing as this is the expected behavior.

According to docs:

You can view the logs of your function executions in the Appwrite Console. Navigate to Functions and click on a function to view its executions.

So the only place we can read the logs is in console... i cant tell my project or client-function... "read the logs from console" we need the responsebody or logs, or something not only the status

barart commented 6 months ago

@noob8boi, thanks for raising this issue! 🙏🏼 As of 1.4, this is the expected behavior. This was done to lift the limit of 1MB response. You'll need to store the data somewhere and fetch it there. I was trying to figure how to resolve this for my case... You said we need to store the data somewhere and fetch it there... but, at least in my case... i need the data of each specific execution... how do i store the data? If i create a execution i got the id of that execution... nice... but the execution itself do not know its id... so the client can have the exeuction id and create a document with that id, but then, how do i put the result of the exeuction to that document? execution will not know the document id neither... even if both know the info they will have a race condition...

2nd approach... client creates a document, retrieve the document id and pass it to the function execution, then the execution could update that document with its results, then client get the status of the execution (getExecution) and if it is already complete retrieve the document updated info and do whatever it need to do... that is what will work for me..

but if for unknown reason, execution could not update the document we are not going to know because there is no way to know the results (only if we log/errors and check console ) and client will fail, so we now need to create a new condition if execution is complete and document is not updated so client knows that something went wrong and some admin can check console and clean database

but its really necessary to force users to do that if executions are already logged on database (table=_X_executions) and we already have the getExecution function? Why just not do things simple? Executions table already have logs and errors, why it cannot just write to a new column called responsebody ,extras, coderesponse or whatever new string and write the res->send to it so getexecution can get it? also, why getexecution do not get errors and logs so clients can use that data too?

also, functions should have another res->key like "passed" if all code runs fine we can put it to true or false so users can get not only the execution status but also a code status ...

sonicviz commented 3 months ago

I've just come across this issue with async implementation, which I initially raised as a documentation issue here: https://github.com/appwrite/appwrite/issues/8382#top (which is still valid, as it is completely undocumented).

However, thinking about it further today I've come to the same conclusion about this requirement to store the async function output in a document, while you need to poll the function continually to get the status.

This design hasn't been fully thought through from an application perspective, and has multiple UX issues.

I'm still scratching my head over why there is no documentation or working examples for such a key feature.

If it is supposedly as simple and foolproof as "use a document" where's the examples demonstrating that for the various unauthenticated and authenticated uses cases, including users potentially firing off multiple parallel running async function calls? How do they retrieve the document associated with a specific function call, without having to write convoluted code to jump through hoops just to get a return call back with the requested data?

Keep it simple. Please!

Are you going to take another look at it at all? This is a key feature, especially now with AI and many tasks easily potentially able to breach the short 30 sec limitation.

I'd also like to request that we get the currently 30 second limit lifted to more reasonable limits, as an optional approach, especially considering the issues noted above with the current async = true method. For example, here is Vercels function limits: https://vercel.com/docs/functions/runtimes image