Closed schlichtanders closed 11 months ago
I think I understood where it comes from
deserialization might fail, and as result return a value identical to the error message (which itself is a bad thing - it should also include the catch_backtrace()
)
https://github.com/JuliaPluto/Malt.jl/blob/34e6226b80ee5f8a16ea0fb4ba5b41d0f00c6284/src/worker.jl#L80
then the Malt message id is changed to Serialization Failure id https://github.com/JuliaPluto/Malt.jl/blob/34e6226b80ee5f8a16ea0fb4ba5b41d0f00c6284/src/worker.jl#L87
then a special handler just rewrites directly to an Exception Failure https://github.com/JuliaPluto/Malt.jl/blob/34e6226b80ee5f8a16ea0fb4ba5b41d0f00c6284/src/worker.jl#L152-L159
and voilá, the original exception happens.
Thank you for the report and investigation. One simple fix could be something like that:
diff --git a/src/worker.jl b/src/worker.jl
index 0aa8240..98d3d0f 100644
--- a/src/worker.jl
+++ b/src/worker.jl
@@ -77,7 +77,7 @@ function serve(server::Sockets.TCPServer)
msg_data, success = try
deserialize(io), true
catch err
- err, false
+ sprint(showerror, err) * sprint(Base.show_backtrace, catch_backtrace()), false
finally
_discard_until_boundary(io)
end
Edit: your suggestion from https://github.com/JuliaPluto/Malt.jl/issues/66 is actually better!
After fixing it slightly myself, it turns out that the ArgumentError is quite special
Remote exception from Malt.Worker on port 9487 with PID 487:
ArgumentError("array must be non-empty")
Looking through the history for "array must be non-empty"
, the only places I could find is pop!
and popfirst!
(the version without default).
https://github.com/JuliaLang/julia/blob/8e5136fa2979885081cd502d2210633dff1d2a1a/base/array.jl#L1330-L1332
function pop!(a::Vector)
if isempty(a)
throw(ArgumentError("array must be non-empty"))
end
Unfortunately, I couldn't find any meaningfull place inside Malt where pop!
is used.
I now switched to Malt DistributedWorker mode and there the error does not appear. So maybe also this ArgumentError is another a Malt bug.
Unfortunately, I couldn't find any meaningfull place inside Malt where pop! is used.
are you using any custom deserialization ?
yes, I have fixed PythonCall's serialization and deserialization to use "dill" instead of "pickle". But maybe it would also happen when using the default PythonCall serialization...
I am also using plain Julia and RCall - and both do work well in Malt, only the PythonCall examples fail immediately because of whatever this underlying error is. With DistributedWorker everything works fine without problems in all three cases.
I probably won't have time debugging this further as the Distributed backend works without problems.
I guess a simple PythonCall test would show it. Here are the serialization method overwrites which I defined in my custom Plutowrapper:
# Fix server Side Python to use dill instead of pickle
function PythonCall.serialize_py(s, x::Py)
if PythonCall.pyisnull(x)
PythonCall.serialize(s, nothing)
else
b = @pyconst(pyimport("dill").dumps)(x)
PythonCall.serialize(s, PythonCall.pybytes_asvector(b))
end
end
function PythonCall.deserialize_py(s)
v = PythonCall.deserialize(s)
if v === nothing
PythonCall.pynew()
else
@pyconst(pyimport("dill").loads)(pybytes(v))
end
end
Maybe this is what breaks Malt, but not Distributed.
I just run into a Malt bug. I cannot reproduce it, but luckily the bug is obvious once seen
(to get this stacktrace I had to do quite a lot...)
Luckily it points to https://github.com/JuliaPluto/Malt.jl/blob/34e6226b80ee5f8a16ea0fb4ba5b41d0f00c6284/src/Malt.jl#L50
which implicitly assumes that
result.value
is of typeString
, which apparently is not always the case. Some extra handling should be setup.