Implement remote evaluation and distributed garbage collection#46
Implement remote evaluation and distributed garbage collection#46jonatanklosko merged 3 commits intomainfrom
Conversation
|
Currently |
| """ | ||
|
|
||
| defexception [:type, :value, :traceback] | ||
| defexception [:lines] |
There was a problem hiding this comment.
Technically it's a breaking change, though ideally I would consider the exception fields to be opaque in this case.
There was a problem hiding this comment.
FTR. I changed it so that we can easily pass Pythonx.Error across nodes without worrying about tracking and going back to the owner for formatting. I don't think storing the separate type, value, traceback objects was a good idea in the first place - if someone is interested in those, they should just have the try-catch in the Python code.
Perhaps we should make it so it will only return the last line? And if they want everything, they can call |
| if (enif_whereis_pid(caller_env, janitor_name, &janitor_pid)) { | ||
| auto device = type == 0 ? eval_info.stdout_device : eval_info.stderr_device; | ||
| // Copy the device term is from a differnet env, so we copy it into | ||
| // the message env, otherwise we may run into unexpected behaviour. |
There was a problem hiding this comment.
Which sort of unexpected behaviour?
There was a problem hiding this comment.
So far it has been working fine. Once I was testing remote eval, where stdout_device and stderr_device are remote pid terms, I run into a weird issue where the message we send below would include a random term (e.g. :infinity, {}) instead of the actual pid. I then revisited the code and realised that those terms are from a different env and doing the copy first fixed the issue. It's interesting that it's only remote pid terms that revealed the issue.
Similarly they could return a tuple with the specific values they need. However, the issue with those approach is that there is no way to return separate values to Elixir side, it would be a single |
Ok, so we are back to square one... with the difference we would be holding fewer things in memory? |
I'm not following. My point is that if we don't return globals, it becomes an actual limitation. |
Co-authored-by: José Valim <jose.valim@gmail.com>
This adds
Pythonx.remote_eval/4to run Python code on another node. Remote eval returns "remote"%Pythonx.Object{}structs and we ensure the corresponding Python objects are kept alive on the owner node as long as necessary. There isPythonx.copy_remote_object/1that serializes the remote object and then deserializes it locally.Pythonx.Objectalso implements theFLAME.Trackableprotocol, which sets up proper lifetime tracking for objects returned fromFLAME.call/3(similarly toPythonx.remote_eval/4.More details on the API in
Pythonxdocs, and implementation details inPythonx.ObjectTracker.We could have a separate
Pythonx.Remotemodule, but the API surface is small, so I am not sure if we necessarily need that.