question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Potential Bug] Unable to pass file to class constructor via `.remote`

See original GitHub issue

Search before asking

  • I searched the issues and found no similar issues.

Ray Component

Ray Core

What happened + What you expected to happen

I am trying to pass a file (or more specifically a file-like object on Windows) to a python class constructor via call to remote. I get a KeyError: file while doing so.

As a user I would expect to things out work fine because opening and reading/writing to a file is possible inside a class constructor but passing the file object of an already opened is not possible.

Is this prohibited due to possible race conditions?

Versions / Dependencies

Ray - master branch.

Python - 3.8.11

OS - Windows 10 Pro

Reproduction script

import ray, tempfile

exit_conditions = ["__ray_terminate__", "ray.actor.exit_actor", "ray.kill"]

@ray.remote
class A():
    def __init__(self, tmpfile, data):
        import atexit

        def f(*args, **kwargs):
            # with open(tmpfile, "w") as f:
            tmpfile.write(data)
            tmpfile.flush()

        atexit.register(f)

    def ready(self):
        pass

    def exit(self):
        ray.actor.exit_actor()

for exit_condition in exit_conditions:

    data = "hello"
    tmpfile = tempfile.NamedTemporaryFile("w+", suffix=".tmp")

    a = A.remote(tmpfile, data)
    ray.get(a.ready.remote())

    if exit_condition == "out_of_scope":
        del a
    elif exit_condition == "__ray_terminate__":
        ray.wait([a.__ray_terminate__.remote()])
    elif exit_condition == "ray.actor.exit_actor":
        ray.wait([a.exit.remote()])
    elif exit_condition == "ray.kill":
        ray.kill(a)
    else:
        assert False, "Unrecognized condition"

    def check_file_written():
        if tmpfile.read() == data:
            return True
        return False

    if exit_condition == "ray.kill":
        assert not check_file_written()

Error

2022-01-14 10:14:06,525 INFO services.py:1382 -- View the Ray dashboard at http://127.0.0.1:8265
 pid=7052) 2022-01-14 10:14:14,743      ERROR serialization.py:289 -- 'file'
 pid=7052) Traceback (most recent call last):
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 287, in deserialize_objects
 pid=7052)     obj = self._deserialize_object(data, metadata, object_ref)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 194, in _deserialize_object
 pid=7052)     return self._deserialize_msgpack_data(data, metadata_fields)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 172, in _desTraceback (most recent call last):

  File "C:\Users\gagan\ray_project\file_pass.py", line 29, in <module>
 pid=7052)     python_objects = self._deserialize_pickle5_data(pickle5_data)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 162, in _deserialize_pickle5_data
    =7052)     obj = pickle.loads(in_band)
ray.get(a.ready.remote())
  File "c:\users\gagan\ray_project\ray\python\ray\_private\client_mode_hook.py", line 105, in wrapper
 pid=7052)   File "C:\ProgramData\Anaconda3\envs\ray_dev\lib\tempfile.py", line 467, in __getattr__
 pid=7052) func(*args, **kwargs)(A
  File "c:\users\gagan\ray_project\ray\python\ray\worker.py", line 1744, in get

    raise value
.pid=7052)ray.exceptions KeyError: 'file'
 pid=7052)The actor died because of an error raised in its creation task,  2022-01-14 10:14:14,759       ERROR worker.py:432 -- Exception raised in creation task: The actor died because of an error raised in its creation task, ray::A.__init__() (pid=7052, ip=127.0.0.1)
  File "python\ray\_raylet.pyx", line 596, in ray._raylet.execute_task
    with core_worker.profile_event(b"task:deserialize_arguments"):
  File "python\ray\_raylet.pyx", line 618, in ray._raylet.execute_task
    raise_if_dependency_failed(arg)
  File "python\ray\_raylet.pyx", line 450, in ray._raylet.raise_if_dependency_failed
    raise arg
ray.exceptions.RaySystemError: System error: 'file'
traceback: Traceback (most recent call last):
  File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 287, in deserialize_objects
    obj = self._deserialize_object(data, metadata, object_ref)
  File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 194, in _deserialize_object
    return self._deserialize_msgpack_data(data, metadata_fields)
  File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 172, in _deserialize_msgpack_data
    python_objects = self._deserialize_pickle5_data(pickle5_data)
  File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 162, in _deserialize_pickle5_data
    obj = pickle.loads(in_band)
  File "C:\ProgramData\Anaconda3\envs\ray_dev\lib\tempfile.py", line 467, in __getattr__
    file = self.__dict__['file']
KeyError: 'file'
ray::A.__init__() (pid=7052, ip=127.0.0.1)
 pid=7052)   File "python\ray\_raylet.pyx", line 596, in ray._raylet.execute_task
 pid=7052)     with core_worker.profile_event(b"task:deserialize_arguments"):
 pid=7052)   File "python\ray\_raylet.pyx", line 618, in ray._raylet.execute_task
 pid=7052)     raise_if_dependency_failed(arg)
 pid=7052)   File "python\ray\_raylet.pyx", line 450, in ray._raylet.raise_if_dependency_failed
 pid=7052)     raise arg
 pid=7052) ray.exceptions.RaySystemError: System error: 'file'
 pid=7052) traceback: Traceback (most recent call last):
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 287, in deserialize_objects
 pid=7052)     obj = self._deserialize_object(data, metadata, object_ref)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 194, in _deserialize_object
 pid=7052)     return self._deserialize_msgpack_data(data, metadata_fields)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 172, in _deserialize_msgpack_data
 pid=7052)     python_objects = self._deserialize_pickle5_data(pickle5_data)
 pid=7052)   File "c:\users\gagan\ray_project\ray\python\ray\serialization.py", line 162, in _deserialize_pickle5_data
 pid=7052)     obj = pickle.loads(in_band)
 pid=7052)   File "C:\ProgramData\Anaconda3\envs\ray_dev\lib\tempfile.py", line 467, in __getattr__
 pid=7052)     file = self.__dict__['file']
 pid=7052) KeyError: 'file'

Anything else

No response

Are you willing to submit a PR?

  • Yes I am willing to submit a PR!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
pcmoritzcommented, Jan 18, 2022

I think it would make to give a better error message here, but it is fine not to support it, since this won’t work on a cluster with many machines for example.

1reaction
czgdp1807commented, Jan 15, 2022

why is the tmpfile getting into the serialized data?

A use case I discovered while fixing https://github.com/ray-project/ray/pull/21484

If passing file-like or file objects is prohibited then we should capture it earlier and raise a TypeError/ValueError for easier understanding.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why can't I pass a String to a @Service class constructor in ...
In my particular case, I am trying to allow for the injection of a String representing the path to a file containing an...
Read more >
Constructors and Destructors - Manual - PHP
Constructor arguments are called by placing the arguments in parentheses after the class name. // Pass both parameters. $p1 = new Point(4, 5);...
Read more >
Java Method/Constructor in Class Cannot be Applied to Given ...
The example in Fig. 2.2 demonstrates how passing an argument of a data type different than what the method expects results in the...
Read more >
Java static code analysis: Utility classes should not have ...
Even abstract utility classes, which can be extended, should not have public constructors. Java adds an implicit public constructor to every class which...
Read more >
Using Constructors - C# Programming Guide | Microsoft Learn
This example shows how a class is instantiated by using the new operator in C#. The simple constructor is invoked after memory is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found