-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Initial high-level code structure of CoreWorker. #4875
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
121b24f
bca82ed
ac1bdc2
8259d9f
35ce1a3
a9b4f12
ea75b8d
dc58275
cd35803
f1ed0da
81c0ff4
2de7c9b
c28e958
450d2b3
804be60
15259e9
d6b7256
7cafd73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #ifndef RAY_COMMON_BUFFER_H | ||
| #define RAY_COMMON_BUFFER_H | ||
|
|
||
| #include <cstdint> | ||
| #include <cstdio> | ||
|
|
||
| namespace ray { | ||
|
|
||
| /// The interface that represents a buffer of bytes. | ||
| class Buffer { | ||
| public: | ||
| /// Pointer to the data. | ||
| virtual uint8_t *Data() const = 0; | ||
|
|
||
| /// Size of this buffer. | ||
| virtual size_t Size() const = 0; | ||
|
|
||
| virtual ~Buffer(); | ||
|
|
||
| bool operator==(const Buffer &rhs) const { | ||
| return this->Data() == rhs.Data() && this->Size() == rhs.Size(); | ||
| } | ||
| }; | ||
|
|
||
| /// Represents a byte buffer in local memory. | ||
| class LocalMemoryBuffer : public Buffer { | ||
| public: | ||
| LocalMemoryBuffer(uint8_t *data, size_t size) : data_(data), size_(size) {} | ||
|
|
||
| uint8_t *Data() const override { return data_; } | ||
|
|
||
| size_t Size() const override { return size_; } | ||
|
|
||
| private: | ||
| /// Pointer to the data. | ||
| uint8_t *data_; | ||
| /// Size of the buffer. | ||
| size_t size_; | ||
| }; | ||
|
|
||
| } // namespace ray | ||
|
|
||
| #endif // RAY_COMMON_BUFFER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #ifndef RAY_CORE_WORKER_COMMON_H | ||
| #define RAY_CORE_WORKER_COMMON_H | ||
|
|
||
| #include <string> | ||
|
|
||
| #include "ray/common/buffer.h" | ||
| #include "ray/id.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| /// Type of this worker. | ||
| enum class WorkerType { WORKER, DRIVER }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What other types make sense here, e.g., does it make sense to have an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, these 2 make sense. That's why WorkerType is an enum, instead of a boolean |
||
|
|
||
| /// Language of Ray tasks and workers. | ||
| enum class Language { PYTHON, JAVA }; | ||
|
|
||
| /// Information about a remote function. | ||
| struct RayFunction { | ||
| /// Language of the remote function. | ||
| const Language language; | ||
| /// Function descriptor of the remote function. | ||
| const std::vector<std::string> function_descriptor; | ||
| }; | ||
|
|
||
| /// Argument of a task. | ||
| class TaskArg { | ||
| public: | ||
| /// Create a pass-by-reference task argument. | ||
| /// | ||
| /// \param[in] object_id Id of the argument. | ||
| /// \return The task argument. | ||
| static TaskArg PassByReference(const ObjectID &object_id) { | ||
| return TaskArg(std::make_shared<ObjectID>(object_id), nullptr); | ||
| } | ||
|
|
||
| /// Create a pass-by-reference task argument. | ||
| /// | ||
| /// \param[in] object_id Id of the argument. | ||
| /// \return The task argument. | ||
| static TaskArg PassByValue(const std::shared_ptr<Buffer> &data) { | ||
| return TaskArg(nullptr, data); | ||
| } | ||
|
|
||
| /// Return true if this argument is passed by reference, false if passed by value. | ||
| bool IsPassedByReference() const { return id_ != nullptr; } | ||
|
|
||
| /// Get the reference object ID. | ||
| ObjectID &GetReference() { | ||
| RAY_CHECK(id_ != nullptr) << "This argument isn't passed by reference."; | ||
| return *id_; | ||
| } | ||
|
|
||
| /// Get the value. | ||
| std::shared_ptr<Buffer> GetValue() { | ||
| RAY_CHECK(data_ != nullptr) << "This argument isn't passed by value."; | ||
| return data_; | ||
| } | ||
|
|
||
| private: | ||
| TaskArg(const std::shared_ptr<ObjectID> id, const std::shared_ptr<Buffer> data) | ||
| : id_(id), data_(data) {} | ||
|
|
||
| /// Id of the argument, if passed by reference, otherwise nullptr. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think of adding a flag explicitly to indicate whether we pass args by ref or by value, so that it will have more readability? And we can get rid of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, will do. |
||
| const std::shared_ptr<ObjectID> id_; | ||
| /// Data of the argument, if passed by value, otherwise nullptr. | ||
| const std::shared_ptr<Buffer> data_; | ||
| }; | ||
|
|
||
| } // namespace ray | ||
|
|
||
| #endif // RAY_CORE_WORKER_COMMON_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #ifndef RAY_CORE_WORKER_CORE_WORKER_H | ||
| #define RAY_CORE_WORKER_CORE_WORKER_H | ||
|
|
||
| #include "common.h" | ||
| #include "object_interface.h" | ||
| #include "ray/common/buffer.h" | ||
| #include "task_execution.h" | ||
| #include "task_interface.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| /// The root class that contains all the core and language-independent functionalities | ||
| /// of the worker. This class is supposed to be used to implement app-language (Java, | ||
| /// Python, etc) workers. | ||
| class CoreWorker { | ||
| public: | ||
| /// Construct a CoreWorker instance. | ||
| /// | ||
| /// \param[in] worker_type Type of this worker. | ||
| /// \param[in] langauge Language of this worker. | ||
| CoreWorker(const WorkerType worker_type, const Language language) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there's a minor difference. using |
||
| : worker_type_(worker_type), | ||
| language_(language), | ||
| task_interface_(*this), | ||
| object_interface_(*this), | ||
| task_execution_interface_(*this){}; | ||
|
|
||
| /// Connect this worker to Raylet. | ||
| Status Connect() { return Status::OK(); } | ||
|
|
||
| /// Type of this worker. | ||
| WorkerType WorkerType() const { return worker_type_; } | ||
|
|
||
| /// Language of this worker. | ||
| Language Language() const { return language_; } | ||
|
|
||
| /// Return the `CoreWorkerTaskInterface` that contains the methods related to task | ||
| /// submisson. | ||
| CoreWorkerTaskInterface &Tasks() { return task_interface_; } | ||
|
|
||
| /// Return the `CoreWorkerObjectInterface` that contains methods related to object | ||
| /// store. | ||
| CoreWorkerObjectInterface &Objects() { return object_interface_; } | ||
|
|
||
| /// Return the `CoreWorkerTaskExecutionInterface` that contains methods related to | ||
| /// task execution. | ||
| CoreWorkerTaskExecutionInterface &Execution() { return task_execution_interface_; } | ||
|
|
||
| private: | ||
| /// Type of this worker. | ||
| const enum WorkerType worker_type_; | ||
|
|
||
| /// Language of this worker. | ||
| const enum Language language_; | ||
|
|
||
| /// The `CoreWorkerTaskInterface` instance. | ||
| CoreWorkerTaskInterface task_interface_; | ||
|
|
||
| /// The `CoreWorkerObjectInterface` instance. | ||
| CoreWorkerObjectInterface object_interface_; | ||
|
|
||
| /// The `CoreWorkerTaskExecutionInterface` instance. | ||
| CoreWorkerTaskExecutionInterface task_execution_interface_; | ||
|
raulchen marked this conversation as resolved.
|
||
| }; | ||
|
|
||
| } // namespace ray | ||
|
|
||
| #endif // RAY_CORE_WORKER_CORE_WORKER_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| #include "gmock/gmock.h" | ||
| #include "gtest/gtest.h" | ||
|
|
||
| #include "core_worker.h" | ||
| #include "ray/common/buffer.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| class CoreWorkerTest : public ::testing::Test { | ||
| public: | ||
| CoreWorkerTest() : core_worker_(WorkerType::WORKER, Language::PYTHON) {} | ||
|
|
||
| protected: | ||
| CoreWorker core_worker_; | ||
| }; | ||
|
|
||
| TEST_F(CoreWorkerTest, TestTaskArg) { | ||
| // Test by-reference argument. | ||
| ObjectID id = ObjectID::from_random(); | ||
| TaskArg by_ref = TaskArg::PassByReference(id); | ||
| ASSERT_TRUE(by_ref.IsPassedByReference()); | ||
| ASSERT_EQ(by_ref.GetReference(), id); | ||
| // Test by-value argument. | ||
| std::shared_ptr<LocalMemoryBuffer> buffer = | ||
| std::make_shared<LocalMemoryBuffer>(static_cast<uint8_t *>(0), 0); | ||
| TaskArg by_value = TaskArg::PassByValue(buffer); | ||
| ASSERT_FALSE(by_value.IsPassedByReference()); | ||
| auto data = by_value.GetValue(); | ||
| ASSERT_TRUE(data != nullptr); | ||
| ASSERT_EQ(*data, *buffer); | ||
| } | ||
|
|
||
| TEST_F(CoreWorkerTest, TestAttributeGetters) { | ||
| ASSERT_EQ(core_worker_.WorkerType(), WorkerType::WORKER); | ||
| ASSERT_EQ(core_worker_.Language(), Language::PYTHON); | ||
| } | ||
|
|
||
| } // namespace ray |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| #include "object_interface.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| Status CoreWorkerObjectInterface::Put(const Buffer &buffer, const ObjectID *object_id) { | ||
| return Status::OK(); | ||
| } | ||
|
|
||
| Status CoreWorkerObjectInterface::Get(const std::vector<ObjectID> &ids, | ||
| int64_t timeout_ms, std::vector<Buffer> *results) { | ||
| return Status::OK(); | ||
| } | ||
|
|
||
| Status CoreWorkerObjectInterface::Wait(const std::vector<ObjectID> &object_ids, | ||
| int num_objects, int64_t timeout_ms, | ||
| std::vector<bool> *results) { | ||
| return Status::OK(); | ||
| } | ||
|
|
||
| Status CoreWorkerObjectInterface::Delete(const std::vector<ObjectID> &object_ids, | ||
| bool local_only, bool delete_creating_tasks) { | ||
| return Status::OK(); | ||
| } | ||
|
|
||
| } // namespace ray |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| #ifndef RAY_CORE_WORKER_OBJECT_INTERFACE_H | ||
| #define RAY_CORE_WORKER_OBJECT_INTERFACE_H | ||
|
|
||
| #include "common.h" | ||
| #include "ray/common/buffer.h" | ||
| #include "ray/id.h" | ||
| #include "ray/status.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| class CoreWorker; | ||
|
|
||
| /// The interface that contains all `CoreWorker` methods that are related to object store. | ||
| class CoreWorkerObjectInterface { | ||
| public: | ||
| CoreWorkerObjectInterface(CoreWorker &core_worker) : core_worker_(core_worker) {} | ||
|
|
||
| /// Put an object into object store. | ||
| /// | ||
| /// \param[in] buffer Data buffer of the object. | ||
|
raulchen marked this conversation as resolved.
|
||
| /// \param[out] object_id Generated ID of the object. | ||
| /// \return Status. | ||
| Status Put(const Buffer &buffer, const ObjectID *object_id); | ||
|
|
||
| /// Get a list of objects from the object store. | ||
| /// | ||
| /// \param[in] ids IDs of the objects to get. | ||
| /// \param[in] timeout_ms Timeout in milliseconds, wait infinitely if it's negative. | ||
| /// \param[out] results Result list of objects data. | ||
| /// \return Status. | ||
| Status Get(const std::vector<ObjectID> &ids, int64_t timeout_ms, | ||
| std::vector<Buffer> *results); | ||
|
|
||
| /// Wait for a list of objects to appear in the object store. | ||
| /// | ||
| /// \param[in] IDs of the objects to wait for. | ||
| /// \param[in] num_returns Number of objects that should appear. | ||
| /// \param[in] timeout_ms Timeout in milliseconds, wait infinitely if it's negative. | ||
| /// \param[out] results A bitset that indicates each object has appeared or not. | ||
| /// \return Status. | ||
| Status Wait(const std::vector<ObjectID> &object_ids, int num_objects, | ||
| int64_t timeout_ms, std::vector<bool> *results); | ||
|
|
||
| /// Delete a list of objects from the object store. | ||
| /// | ||
| /// \param[in] object_ids IDs of the objects to delete. | ||
| /// \param[in] local_only Whether only delete the objects in local node, or all nodes in | ||
| /// the cluster. | ||
| /// \param[in] delete_creating_tasks Whether also delete the tasks that | ||
| /// created these objects. \return Status. | ||
| Status Delete(const std::vector<ObjectID> &object_ids, bool local_only, | ||
| bool delete_creating_tasks); | ||
|
|
||
| private: | ||
| /// Reference to the parent CoreWorker instance. | ||
| CoreWorker &core_worker_; | ||
| }; | ||
|
|
||
| } // namespace ray | ||
|
|
||
| #endif // RAY_CORE_WORKER_OBJECT_INTERFACE_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| #include "task_execution.h" | ||
|
|
||
| namespace ray { | ||
|
|
||
| void CoreWorkerTaskExecutionInterface::Start(const TaskExecutor &executor) {} | ||
|
|
||
| } // namespace ray |
Uh oh!
There was an error while loading. Please reload this page.