From fa03f848994150295505b0c72cc09612657d8291 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 16:14:09 +0800 Subject: [PATCH 1/9] fix: rename yr to yuanrong --- .gitignore | 54 +-- api/python/{yr => yuanrong}/__init__.py | 28 +- .../{yr => yuanrong}/accelerate/__init__.py | 0 .../{yr => yuanrong}/accelerate/executor.py | 6 +- .../accelerate/shm_broadcast.py | 8 +- api/python/{yr => yuanrong}/affinity.py | 0 api/python/{yr => yuanrong}/apis.py | 372 +++++++++--------- .../{yr => yuanrong}/cluster_mode_runtime.py | 26 +- api/python/{yr => yuanrong}/code_manager.py | 12 +- .../{yr => yuanrong}/common/__init__.py | 0 .../{yr => yuanrong}/common/constants.py | 0 .../{yr => yuanrong}/common/singleton.py | 0 api/python/{yr => yuanrong}/common/types.py | 0 api/python/{yr => yuanrong}/common/utils.py | 8 +- .../{yr => yuanrong}/compiled_dag_ref.py | 26 +- api/python/{yr => yuanrong}/config.py | 36 +- .../config/python-runtime-log.json | 0 api/python/{yr => yuanrong}/config_manager.py | 10 +- .../{yr => yuanrong}/decorator/__init__.py | 0 .../decorator/function_proxy.py | 52 +-- .../decorator/instance_proxy.py | 42 +- api/python/{yr => yuanrong}/device.py | 4 +- api/python/{yr => yuanrong}/err_type.py | 0 api/python/{yr => yuanrong}/exception.py | 8 +- .../{yr => yuanrong}/executor/__init__.py | 0 .../{yr => yuanrong}/executor/executor.py | 16 +- .../executor/faas_executor.py | 20 +- .../{yr => yuanrong}/executor/faas_handler.py | 10 +- .../executor/function_handler.py | 24 +- .../{yr => yuanrong}/executor/handler_intf.py | 2 +- .../executor/instance_manager.py | 4 +- .../executor/posix_handler.py | 2 +- api/python/{yr => yuanrong}/fcc.py | 58 +-- api/python/{yr => yuanrong}/fnruntime.pyx | 0 .../{yr => yuanrong}/functionsdk/__init__.py | 0 .../{yr => yuanrong}/functionsdk/context.py | 6 +- .../functionsdk/error_code.py | 0 .../{yr => yuanrong}/functionsdk/function.py | 18 +- .../{yr => yuanrong}/functionsdk/logger.py | 2 +- .../functionsdk/logger_manager.py | 4 +- .../{yr => yuanrong}/functionsdk/utils.py | 0 api/python/{yr => yuanrong}/generator.py | 8 +- api/python/{yr => yuanrong}/group.py | 4 +- .../{yr => yuanrong}/includes/__init__.pxd | 0 .../{yr => yuanrong}/includes/affinity.pxd | 0 .../{yr => yuanrong}/includes/affinity.pxi | 0 .../{yr => yuanrong}/includes/buffer.pxi | 0 .../{yr => yuanrong}/includes/libruntime.pxd | 2 +- .../{yr => yuanrong}/includes/libruntime.pxi | 0 .../includes/serialization.pxi | 0 .../{yr => yuanrong}/local_mode/__init__.py | 0 .../local_mode/dependency_manager.py | 6 +- .../{yr => yuanrong}/local_mode/instance.py | 0 .../local_mode/instance_manager.py | 16 +- .../local_mode/local_client.py | 8 +- .../local_mode/local_mode_runtime.py | 34 +- .../local_mode/local_object_store.py | 2 +- .../{yr => yuanrong}/local_mode/scheduler.py | 4 +- .../local_mode/task_manager.py | 24 +- .../{yr => yuanrong}/local_mode/task_spec.py | 4 +- .../{yr => yuanrong}/local_mode/timer.py | 2 +- .../{yr => yuanrong}/local_mode/worker.py | 16 +- api/python/{yr => yuanrong}/log.py | 4 +- api/python/{yr => yuanrong}/main/__init__.py | 0 .../{yr => yuanrong}/main/yr_runtime_main.py | 10 +- api/python/{yr => yuanrong}/metrics.py | 96 ++--- api/python/{yr => yuanrong}/object_ref.py | 18 +- api/python/{yr => yuanrong}/resource_group.py | 22 +- .../{yr => yuanrong}/resource_group_ref.py | 4 +- api/python/{yr => yuanrong}/runtime.py | 14 +- api/python/{yr => yuanrong}/runtime_env.py | 2 +- api/python/{yr => yuanrong}/runtime_holder.py | 10 +- .../serialization/__init__.py | 2 +- .../serialization/serialization.py | 12 +- .../serialization/serializers.py | 12 +- api/python/{yr => yuanrong}/signature.py | 0 api/python/{yr => yuanrong}/stream.py | 0 api/python/{yr => yuanrong}/tests/BUILD.bazel | 0 .../tests/test_InvokeOptions.py | 6 +- .../{yr => yuanrong}/tests/test_apis.py | 240 +++++------ .../{yr => yuanrong}/tests/test_apis_get.py | 12 +- .../{yr => yuanrong}/tests/test_apis_put.py | 56 +-- .../tests/test_cluster_mode_runtime.py | 26 +- .../tests/test_code_manager.py | 14 +- .../{yr => yuanrong}/tests/test_common.py | 2 +- .../{yr => yuanrong}/tests/test_decorator.py | 18 +- .../{yr => yuanrong}/tests/test_executor.py | 26 +- .../tests/test_faas_handler.py | 22 +- api/python/{yr => yuanrong}/tests/test_fcc.py | 28 +- .../tests/test_function_handler.py | 14 +- .../tests/test_functionsdk.py | 22 +- .../{yr => yuanrong}/tests/test_generator.py | 18 +- .../tests/test_instance_manager.py | 2 +- .../{yr => yuanrong}/tests/test_local_mode.py | 44 +-- .../{yr => yuanrong}/tests/test_metrics.py | 12 +- .../tests/test_runtime_env.py | 2 +- .../tests/test_serialization.py | 8 +- 97 files changed, 863 insertions(+), 903 deletions(-) rename api/python/{yr => yuanrong}/__init__.py (82%) rename api/python/{yr => yuanrong}/accelerate/__init__.py (100%) rename api/python/{yr => yuanrong}/accelerate/executor.py (97%) rename api/python/{yr => yuanrong}/accelerate/shm_broadcast.py (98%) rename api/python/{yr => yuanrong}/affinity.py (100%) rename api/python/{yr => yuanrong}/apis.py (85%) rename api/python/{yr => yuanrong}/cluster_mode_runtime.py (96%) rename api/python/{yr => yuanrong}/code_manager.py (97%) rename api/python/{yr => yuanrong}/common/__init__.py (100%) rename api/python/{yr => yuanrong}/common/constants.py (100%) rename api/python/{yr => yuanrong}/common/singleton.py (100%) rename api/python/{yr => yuanrong}/common/types.py (100%) rename api/python/{yr => yuanrong}/common/utils.py (99%) rename api/python/{yr => yuanrong}/compiled_dag_ref.py (92%) rename api/python/{yr => yuanrong}/config.py (96%) rename api/python/{yr => yuanrong}/config/python-runtime-log.json (100%) rename api/python/{yr => yuanrong}/config_manager.py (97%) rename api/python/{yr => yuanrong}/decorator/__init__.py (100%) rename api/python/{yr => yuanrong}/decorator/function_proxy.py (90%) rename api/python/{yr => yuanrong}/decorator/instance_proxy.py (96%) rename api/python/{yr => yuanrong}/device.py (97%) rename api/python/{yr => yuanrong}/err_type.py (100%) rename api/python/{yr => yuanrong}/exception.py (97%) rename api/python/{yr => yuanrong}/executor/__init__.py (100%) rename api/python/{yr => yuanrong}/executor/executor.py (89%) rename api/python/{yr => yuanrong}/executor/faas_executor.py (94%) rename api/python/{yr => yuanrong}/executor/faas_handler.py (83%) rename api/python/{yr => yuanrong}/executor/function_handler.py (92%) rename api/python/{yr => yuanrong}/executor/handler_intf.py (97%) rename api/python/{yr => yuanrong}/executor/instance_manager.py (97%) rename api/python/{yr => yuanrong}/executor/posix_handler.py (95%) rename api/python/{yr => yuanrong}/fcc.py (80%) rename api/python/{yr => yuanrong}/fnruntime.pyx (100%) rename api/python/{yr => yuanrong}/functionsdk/__init__.py (100%) rename api/python/{yr => yuanrong}/functionsdk/context.py (99%) rename api/python/{yr => yuanrong}/functionsdk/error_code.py (100%) rename api/python/{yr => yuanrong}/functionsdk/function.py (96%) rename api/python/{yr => yuanrong}/functionsdk/logger.py (98%) rename api/python/{yr => yuanrong}/functionsdk/logger_manager.py (98%) rename api/python/{yr => yuanrong}/functionsdk/utils.py (100%) rename api/python/{yr => yuanrong}/generator.py (96%) rename api/python/{yr => yuanrong}/group.py (94%) rename api/python/{yr => yuanrong}/includes/__init__.pxd (100%) rename api/python/{yr => yuanrong}/includes/affinity.pxd (100%) rename api/python/{yr => yuanrong}/includes/affinity.pxi (100%) rename api/python/{yr => yuanrong}/includes/buffer.pxi (100%) rename api/python/{yr => yuanrong}/includes/libruntime.pxd (99%) rename api/python/{yr => yuanrong}/includes/libruntime.pxi (100%) rename api/python/{yr => yuanrong}/includes/serialization.pxi (100%) rename api/python/{yr => yuanrong}/local_mode/__init__.py (100%) rename api/python/{yr => yuanrong}/local_mode/dependency_manager.py (94%) rename api/python/{yr => yuanrong}/local_mode/instance.py (100%) rename api/python/{yr => yuanrong}/local_mode/instance_manager.py (94%) rename api/python/{yr => yuanrong}/local_mode/local_client.py (92%) rename api/python/{yr => yuanrong}/local_mode/local_mode_runtime.py (95%) rename api/python/{yr => yuanrong}/local_mode/local_object_store.py (99%) rename api/python/{yr => yuanrong}/local_mode/scheduler.py (95%) rename api/python/{yr => yuanrong}/local_mode/task_manager.py (93%) rename api/python/{yr => yuanrong}/local_mode/task_spec.py (91%) rename api/python/{yr => yuanrong}/local_mode/timer.py (98%) rename api/python/{yr => yuanrong}/local_mode/worker.py (93%) rename api/python/{yr => yuanrong}/log.py (98%) rename api/python/{yr => yuanrong}/main/__init__.py (100%) rename api/python/{yr => yuanrong}/main/yr_runtime_main.py (94%) rename api/python/{yr => yuanrong}/metrics.py (88%) rename api/python/{yr => yuanrong}/object_ref.py (92%) rename api/python/{yr => yuanrong}/resource_group.py (81%) rename api/python/{yr => yuanrong}/resource_group_ref.py (93%) rename api/python/{yr => yuanrong}/runtime.py (98%) rename api/python/{yr => yuanrong}/runtime_env.py (99%) rename api/python/{yr => yuanrong}/runtime_holder.py (86%) rename api/python/{yr => yuanrong}/serialization/__init__.py (87%) rename api/python/{yr => yuanrong}/serialization/serialization.py (93%) rename api/python/{yr => yuanrong}/serialization/serializers.py (96%) rename api/python/{yr => yuanrong}/signature.py (100%) rename api/python/{yr => yuanrong}/stream.py (100%) rename api/python/{yr => yuanrong}/tests/BUILD.bazel (100%) rename api/python/{yr => yuanrong}/tests/test_InvokeOptions.py (97%) rename api/python/{yr => yuanrong}/tests/test_apis.py (70%) rename api/python/{yr => yuanrong}/tests/test_apis_get.py (81%) rename api/python/{yr => yuanrong}/tests/test_apis_put.py (68%) rename api/python/{yr => yuanrong}/tests/test_cluster_mode_runtime.py (94%) rename api/python/{yr => yuanrong}/tests/test_code_manager.py (93%) rename api/python/{yr => yuanrong}/tests/test_common.py (99%) rename api/python/{yr => yuanrong}/tests/test_decorator.py (92%) rename api/python/{yr => yuanrong}/tests/test_executor.py (82%) rename api/python/{yr => yuanrong}/tests/test_faas_handler.py (89%) rename api/python/{yr => yuanrong}/tests/test_fcc.py (87%) rename api/python/{yr => yuanrong}/tests/test_function_handler.py (95%) rename api/python/{yr => yuanrong}/tests/test_functionsdk.py (95%) rename api/python/{yr => yuanrong}/tests/test_generator.py (90%) rename api/python/{yr => yuanrong}/tests/test_instance_manager.py (95%) rename api/python/{yr => yuanrong}/tests/test_local_mode.py (88%) rename api/python/{yr => yuanrong}/tests/test_metrics.py (93%) rename api/python/{yr => yuanrong}/tests/test_runtime_env.py (99%) rename api/python/{yr => yuanrong}/tests/test_serialization.py (93%) diff --git a/.gitignore b/.gitignore index 13ae276..06ce896 100644 --- a/.gitignore +++ b/.gitignore @@ -1,47 +1,7 @@ -bazel-* -.vscode -.clangd -.cache -.idea -.clwb -.ijwb -external -api/cpp/example/3rd -genhtml -compile_commands.json -pyrightconfig.json - -# cpp -*.pb.* -lib*_proto.* - -# java -target/ -*.jar -*.lst -dependency-reduced-pom.xml - -# python -__pycache__ -api/python/yr.egg-info -api/python/dist/*.whl -api/python/yr/*.so* -api/python/yr/libruntime_pb2.py -test/st/python/**/*.log* -test/st/python/pkg - -# test -test/st/cpp/gtest -test/st/yuanrong/ -test/st/**/output.txt -test/st/functions/pkg -test/st/functions/**/*.so -test/st/functions/**/*.zip -test/st/functions/**/*.xml -functionsystem -datasystem -metrics -#thirdparty -thirdparty -go/pkg/mod/ -cmake-build-debug +**/build/ +/output/ +*.so +__pycache__/ +*.pyc +thirdparty/ +api/cpp/example/3rd/ diff --git a/api/python/yr/__init__.py b/api/python/yuanrong/__init__.py similarity index 82% rename from api/python/yr/__init__.py rename to api/python/yuanrong/__init__.py index ee7c994..d0c0395 100644 --- a/api/python/yr/__init__.py +++ b/api/python/yuanrong/__init__.py @@ -15,7 +15,7 @@ # limitations under the License. """ -yr api +yuanrong api """ import os import ctypes @@ -49,7 +49,7 @@ for so_path in [ # E402: import not at top of file # We must load so before import datasystem, so the lint is not really useful -from yr.apis import ( # noqa: E402 +from yuanrong.apis import ( # noqa: E402 init, finalize, put, get, invoke, instance, wait, cancel, method, exit, @@ -62,28 +62,28 @@ from yr.apis import ( # noqa: E402 list_named_instances ) -from yr.fcc import ( # noqa: E402 +from yuanrong.fcc import ( # noqa: E402 create_function_group, get_function_group_context ) -from yr.resource_group import ResourceGroup # noqa: E402 -from yr.runtime import ( # noqa: E402 +from yuanrong.resource_group import ResourceGroup # noqa: E402 +from yuanrong.runtime import ( # noqa: E402 ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, AlarmSeverity, AlarmInfo, ConsistencyType, GetParams, GetParam ) -from yr.config import ( # noqa: E402 +from yuanrong.config import ( # noqa: E402 Config, InvokeOptions, UserTLSConfig, FunctionGroupOptions, SchedulingAffinityType, FunctionGroupContext, ServerInfo, DeviceInfo, ResourceGroupOptions, GroupOptions, ) -from yr.group import Group -from yr.stream import ProducerConfig, SubscriptionConfig, Element # noqa: E402 -from yr.functionsdk.function import Function # noqa: E402 -from yr.functionsdk.context import Context # noqa: E402 -from yr.affinity import Affinity, AffinityType, AffinityKind, AffinityScope, LabelOperator, OperatorType # noqa: E402 -from yr.metrics import Gauge, Alarm, UInt64Counter, DoubleCounter # noqa: E402 +from yuanrong.group import Group +from yuanrong.stream import ProducerConfig, SubscriptionConfig, Element # noqa: E402 +from yuanrong.functionsdk.function import Function # noqa: E402 +from yuanrong.functionsdk.context import Context # noqa: E402 +from yuanrong.affinity import Affinity, AffinityType, AffinityKind, AffinityScope, LabelOperator, OperatorType # noqa: E402 +from yuanrong.metrics import Gauge, Alarm, UInt64Counter, DoubleCounter # noqa: E402 -from yr.decorator.function_proxy import FunctionProxy # noqa: E402 -from yr.decorator.instance_proxy import ( # noqa: E402 +from yuanrong.decorator.function_proxy import FunctionProxy # noqa: E402 +from yuanrong.decorator.instance_proxy import ( # noqa: E402 InstanceCreator, InstanceProxy, MethodProxy, FunctionGroupHandler, FunctionGroupMethodProxy) __all__ = [ diff --git a/api/python/yr/accelerate/__init__.py b/api/python/yuanrong/accelerate/__init__.py similarity index 100% rename from api/python/yr/accelerate/__init__.py rename to api/python/yuanrong/accelerate/__init__.py diff --git a/api/python/yr/accelerate/executor.py b/api/python/yuanrong/accelerate/executor.py similarity index 97% rename from api/python/yr/accelerate/executor.py rename to api/python/yuanrong/accelerate/executor.py index 904016b..b13427e 100644 --- a/api/python/yr/accelerate/executor.py +++ b/api/python/yuanrong/accelerate/executor.py @@ -19,9 +19,9 @@ import traceback import threading import asyncio from typing import Dict, Tuple, Optional -from yr import log -from yr.accelerate.shm_broadcast import MessageQueue, ResponseStatus, STOP_EVENT -from yr.executor.instance_manager import InstanceManager +from yuanrong import log +from yuanrong.accelerate.shm_broadcast import MessageQueue, ResponseStatus, STOP_EVENT +from yuanrong.executor.instance_manager import InstanceManager ACCELERATE_WORKER = None diff --git a/api/python/yr/accelerate/shm_broadcast.py b/api/python/yuanrong/accelerate/shm_broadcast.py similarity index 98% rename from api/python/yr/accelerate/shm_broadcast.py rename to api/python/yuanrong/accelerate/shm_broadcast.py index edcad1c..7d98f82 100644 --- a/api/python/yr/accelerate/shm_broadcast.py +++ b/api/python/yuanrong/accelerate/shm_broadcast.py @@ -23,8 +23,8 @@ from contextlib import contextmanager, asynccontextmanager from typing import Optional from enum import IntEnum from dataclasses import dataclass -from yr import log -import yr +from yuanrong import log +import yuanrong STOP_EVENT = threading.Event() USE_SCHED_YIELD = ((sys.version_info[:3] >= (3, 11, 1)) @@ -67,14 +67,14 @@ class ShmRingBuffer: self.data_offset = 0 self.metadata_offset = self.max_chunk_bytes * self.max_chunks if name is None: - obj_id, shared_memory = yr.runtime_holder.global_runtime.get_runtime().create_buffer( + obj_id, shared_memory = yuanrong.runtime_holder.global_runtime.get_runtime().create_buffer( self.total_bytes_of_buffer) self.name = obj_id self.shared_memory = shared_memory self.shared_memory.get_buf()[:] = bytes(len(self.shared_memory.get_buf())) else: self.name = name - self.shared_memory = yr.runtime_holder.global_runtime.get_runtime().get_buffer(name) + self.shared_memory = yuanrong.runtime_holder.global_runtime.get_runtime().get_buffer(name) def handle(self): """message queue handle""" diff --git a/api/python/yr/affinity.py b/api/python/yuanrong/affinity.py similarity index 100% rename from api/python/yr/affinity.py rename to api/python/yuanrong/affinity.py diff --git a/api/python/yr/apis.py b/api/python/yuanrong/apis.py similarity index 85% rename from api/python/yr/apis.py rename to api/python/yuanrong/apis.py index e029809..df01961 100644 --- a/api/python/yr/apis.py +++ b/api/python/yuanrong/apis.py @@ -22,26 +22,26 @@ import logging import os from typing import List, Dict, Optional, Tuple, Union -from yr.libruntime_pb2 import LanguageType - -from yr import log, runtime_holder -from yr.code_manager import CodeManager -from yr.common import constants, utils -from yr.config import ClientInfo, Config, InvokeOptions -from yr.config_manager import ConfigManager -from yr.decorator import function_proxy, instance_proxy -from yr.executor.executor import Executor -from yr.fnruntime import Consumer, Producer, auto_get_cluster_access_info -from yr.object_ref import ObjectRef -from yr.resource_group_ref import RgObjectRef -from yr.runtime import ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, GetParams -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.decorator.function_proxy import FunctionProxy -from yr.decorator.instance_proxy import InstanceCreator, InstanceProxy -from yr.common.utils import CrossLanguageInfo -from yr.resource_group import ResourceGroup - -from yr.serialization import Serialization +from yuanrong.libruntime_pb2 import LanguageType + +from yuanrong import log, runtime_holder +from yuanrong.code_manager import CodeManager +from yuanrong.common import constants, utils +from yuanrong.config import ClientInfo, Config, InvokeOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.executor.executor import Executor +from yuanrong.fnruntime import Consumer, Producer, auto_get_cluster_access_info +from yuanrong.object_ref import ObjectRef +from yuanrong.resource_group_ref import RgObjectRef +from yuanrong.runtime import ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.decorator.function_proxy import FunctionProxy +from yuanrong.decorator.instance_proxy import InstanceCreator, InstanceProxy +from yuanrong.common.utils import CrossLanguageInfo +from yuanrong.resource_group import ResourceGroup + +from yuanrong.serialization import Serialization __g_is_init = False _MAX_INT = 0x7FFFFFFF @@ -136,19 +136,19 @@ def init(conf: Config = None) -> ClientInfo: The context information of this invocation. Data type is ClientInfo. Raises: - RuntimeError: If yr.init is called more than once. + RuntimeError: If yuanrong.init is called more than once. TypeError: If the parameter type is incorrect. ValueError: If the parameter value is incorrect. Example: - >>> import yr + >>> import yuanrong >>> - >>> conf = yr.Config() - >>> yr.init(conf) + >>> conf = yuanrong.Config() + >>> yuanrong.init(conf) """ if is_initialized() and ConfigManager().is_driver: - raise RuntimeError("yr.init cannot be called twice") + raise RuntimeError("yuanrong.init cannot be called twice") conf = Config() if conf is None else conf @@ -184,16 +184,16 @@ def finalize() -> None: Raises: - RuntimeError: This exception will be thrown if ``finalize`` is called without initializing ``yr``. + RuntimeError: This exception will be thrown if ``finalize`` is called without initializing ``yuanrong``. Returns: None. Examples: - >>> import yr - >>> conf = yr.Config() - >>> yr.init(conf) - >>> yr.finalize() + >>> import yuanrong + >>> conf = yuanrong.Config() + >>> yuanrong.init(conf) + >>> yuanrong.finalize() """ global __g_is_init if not __g_is_init: @@ -218,7 +218,7 @@ def put(obj: object, create_param: CreateParam = CreateParam()) -> ObjectRef: Put an object to datasystem. Note: - 1. this method should be used after `yr.init()`. + 1. this method should be used after `yuanrong.init()`. 2. If the type of put is memoryview, bytearray or bytes, serialization is omitted at this time. 3. If the object passed to put() is of type memoryview, bytearray, or bytes, its length must not be ``0``. @@ -233,25 +233,25 @@ def put(obj: object, create_param: CreateParam = CreateParam()) -> ObjectRef: ValueError: If the input `obj` is `None` or a zero-length `bytes`, `bytearray`, or `memoryview` object. TypeError: If the input obj is already an `ObjectRef`. TypeError: If the input obj is not serializable, e.g. `thread.RLock`. - RuntimeError: Call `yr.put()` before `yr.init()`. + RuntimeError: Call `yuanrong.put()` before `yuanrong.init()`. RuntimeError: Failed to put to datasystem. Examples: - >>> import yr - >>> yr.init() - >>> param = yr.CreateParam() - >>> param.cache_type = yr.CacheType.DISK + >>> import yuanrong + >>> yuanrong.init() + >>> param = yuanrong.CreateParam() + >>> param.cache_type = yuanrong.CacheType.DISK >>> bs = bytes(0) >>> mem = memoryview(bytes(100)) - >>> obj_ref2 = yr.put(mem) - >>> print(yr.get(obj_ref2)) + >>> obj_ref2 = yuanrong.put(mem) + >>> print(yuanrong.get(obj_ref2)) >>> # The final print output is a memoryview pointer. >>> byte_array = bytearray(20) - >>> obj_ref3 = yr.put(byte_array) - >>> print(yr.get(obj_ref3)) + >>> obj_ref3 = yuanrong.put(byte_array) + >>> print(yuanrong.get(obj_ref3)) >>> # The final print output is a memoryview pointer. - >>> obj_ref4 = yr.put(100) - >>> print(yr.get(obj_ref4)) + >>> obj_ref4 = yuanrong.put(100) + >>> print(yuanrong.get(obj_ref4)) """ if obj is None or (isinstance(obj, (bytes, bytearray, memoryview)) and len(obj) == 0): raise ValueError("value is None or has zero length") @@ -271,7 +271,7 @@ def get(obj_refs: Union["ObjectRef", List, "RgObjectRef"], timeout: int = consta The interface call will block until the object's value is obtained or a timeout occurs. Note: - yr.get() uniformly returns a memoryview pointer for bytes, bytearray, and memoryview types. + yuanrong.get() uniformly returns a memoryview pointer for bytes, bytearray, and memoryview types. Args: obj_refs (ObjectRef, List[ObjectRef]): The object_ref of the object in the data system. @@ -292,17 +292,17 @@ def get(obj_refs: Union["ObjectRef", List, "RgObjectRef"], timeout: int = consta TimeoutError: If the results of all object references cannot be obtained within the specified timeout period. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke() + >>> @yuanrong.invoke() >>> def add(a, b): ... return a + b >>> obj_ref_1 = add.invoke(1, 2) >>> obj_ref_2 = add.invoke(3, 4) - >>> result = yr.get([obj_ref_1, obj_ref_2], timeout=-1) + >>> result = yuanrong.get([obj_ref_1, obj_ref_2], timeout=-1) >>> print(result) - >>> yr.finalize() + >>> yuanrong.finalize() """ if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: @@ -355,12 +355,12 @@ def wait(obj_refs: Union[ObjectRef, List[ObjectRef]], wait_num: int = 1, ValueError: If the input parameter is incorrect. Examples: - >>> import yr + >>> import yuanrong >>> import time >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo(a): ... time.sleep(a) ... return "sleep:", a @@ -369,12 +369,12 @@ def wait(obj_refs: Union[ObjectRef, List[ObjectRef]], wait_num: int = 1, >>> >>> wait_num = 3 >>> timeout = 10 - >>> result = yr.wait(res, wait_num, timeout) + >>> result = yuanrong.wait(res, wait_num, timeout) >>> print("ready_list = ", result[0], "unready_list = ", result[1]) - >>> print(yr.get(result[0])) + >>> print(yuanrong.get(result[0])) [('sleep:', 0), ('sleep:', 1)] >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if timeout is None: timeout = -1 @@ -438,16 +438,16 @@ def cancel(obj_refs: Union[ObjectRef, List[ObjectRef]], allow_force: bool = _DEF Examples: >>> import time - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke >>> def func(): >>> time.sleep(100) >>> >>> ret = func.invoke() - >>> yr.cancel(ret) - >>> yr.finalize() + >>> yuanrong.cancel(ret) + >>> yuanrong.finalize() """ if isinstance(obj_refs, ObjectRef): obj_refs = [obj_refs] @@ -481,28 +481,28 @@ def invoke(*args, **kwargs) -> function_proxy.FunctionProxy: Examples: Simple invocation example: - >>> import yr - >>> yr.init() - >>> @yr.invoke + >>> import yuanrong + >>> yuanrong.init() + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> ret = add.invoke(1, 2) - >>> print(yr.get(ret)) - >>> yr.finalize() + >>> print(yuanrong.get(ret)) + >>> yuanrong.finalize() Function invocation example: - >>> import yr - >>> yr.init() - >>> @yr.invoke + >>> import yuanrong + >>> yuanrong.init() + >>> @yuanrong.invoke ... def func1(a): ... return a + " func1" - >>> @yr.invoke + >>> @yuanrong.invoke ... def func2(a): - ... return yr.get(func1.invoke(a)) + " func2" + ... return yuanrong.get(func1.invoke(a)) + " func2" >>> ret = func2.invoke("hello") - >>> print(yr.get(ret)) - >>> yr.finalize() + >>> print(yuanrong.get(ret)) + >>> yuanrong.finalize() """ if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): return function_proxy.make_decorator()(args[0]) @@ -518,7 +518,7 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: Args: class (class): The class that needs to be remotely invoked. - invoke_options (yr.InvokeOptions): Invocation parameters. + invoke_options (yuanrong.InvokeOptions): Invocation parameters. Returns: The creator of the decorated class. @@ -529,10 +529,10 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: Example: Simple invocation example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... def add(self, a): @@ -541,18 +541,18 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: ... return self.sum >>> >>> ins = Instance.invoke() - >>> yr.get(ins.add.invoke(1)) - >>> print(yr.get(ins.get.invoke())) + >>> yuanrong.get(ins.add.invoke(1)) + >>> print(yuanrong.get(ins.get.invoke())) 1 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() Function invocation example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... def __init__(self): ... self.sum = 0 @@ -561,22 +561,22 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: ... def get(self): ... return self.sum - >>> @yr.instance + >>> @yuanrong.instance ... class Instance2: ... def __init__(self): ... self.ins = Instance.invoke() ... def add(self, a): ... return self.ins.add.invoke(a) ... def get(self): - ... return yr.get(self.ins.get.invoke()) + ... return yuanrong.get(self.ins.get.invoke()) >>> >>> ins = Instance2.invoke() - >>> yr.get(ins.add.invoke(2)) - >>> print(yr.get(ins.get.invoke())) + >>> yuanrong.get(ins.add.invoke(2)) + >>> print(yuanrong.get(ins.get.invoke())) 2 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): @@ -601,10 +601,10 @@ def method(*args, **kwargs): TypeError: If the type of the input parameters is incorrect. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... @@ -614,19 +614,19 @@ def method(*args, **kwargs): ... def get(self): ... return self.sum ... - ... @yr.method(return_nums=2) + ... @yuanrong.method(return_nums=2) ... def detail(self, a, b): ... return a, b ... >>> ins = Instance.invoke() >>> res1, res2 = ins.detail.invoke(0, 1) - >>> print("detail result1:", yr.get(res1)) + >>> print("detail result1:", yuanrong.get(res1)) detail result1: 0 - >>> print("detail result2:", yr.get(res2)) + >>> print("detail result2:", yuanrong.get(res2)) detail result2: 1 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if "concurrency_group" in kwargs and len(args) == 0: kwargs.pop("concurrency_group") @@ -821,12 +821,12 @@ def kv_write(key: str, value: bytes, existence: ExistenceOpt = ExistenceOpt.NONE RuntimeError: If the data fails to be written to the data system. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> yr.kv_write("kv-key", b"value1", yr.ExistenceOpt.NONE, yr.WriteMode.NONE_L2_CACHE, 0, yr.CacheType.MEMORY) + >>> yuanrong.kv_write("kv-key", b"value1", yuanrong.ExistenceOpt.NONE, yuanrong.WriteMode.NONE_L2_CACHE, 0, yuanrong.CacheType.MEMORY) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ set_param = SetParam() set_param.existence = existence @@ -857,18 +857,18 @@ def kv_write_with_param(key: str, value: bytes, set_param: SetParam) -> None: RuntimeError: If the data fails to be written to the data system. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> set_param = yr.SetParam() - >>> set_param.existence = yr.ExistenceOpt.NX - >>> set_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> set_param = yuanrong.SetParam() + >>> set_param.existence = yuanrong.ExistenceOpt.NX + >>> set_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> set_param.ttl_second = 10 - >>> set_param.cache_type = yr.CacheType.DISK - >>> yr.kv_write_with_param("kv-key", b"value1", set_param) + >>> set_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_write_with_param("kv-key", b"value1", set_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ runtime_holder.global_runtime.get_runtime().kv_write(key, value, set_param) @@ -895,18 +895,18 @@ def kv_m_write_tx(keys: List[str], values: List[bytes], m_set_param: MSetParam = If data writing to the data system fails. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> mset_param = yr.MSetParam() - >>> mset_param.existence = yr.ExistenceOpt.NX - >>> mset_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> mset_param = yuanrong.MSetParam() + >>> mset_param.existence = yuanrong.ExistenceOpt.NX + >>> mset_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> mset_param.ttl_second = 100 - >>> mset_param.cache_type = yr.CacheType.DISK - >>> yr.kv_m_write_tx(["key1", "key2"], [b"value1", b"value2"], mset_param) + >>> mset_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_m_write_tx(["key1", "key2"], [b"value1", b"value2"], mset_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if len(keys) != len(values): raise ValueError( @@ -938,7 +938,7 @@ def kv_read( RuntimeError: If data retrieval from the data system fails. Example: - >>> v1 = yr.kv_read("kv-key") + >>> v1 = yuanrong.kv_read("kv-key") """ is_single_obj = isinstance(key, str) rets = runtime_holder.global_runtime.get_runtime().kv_read(key, timeout) @@ -966,18 +966,18 @@ def kv_set(key: str, value: bytes, set_param: SetParam = SetParam()) -> None: RuntimeError: If the data writing to the data system fails. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> set_param = yr.SetParam() - >>> set_param.existence = yr.ExistenceOpt.NX - >>> set_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> set_param = yuanrong.SetParam() + >>> set_param.existence = yuanrong.ExistenceOpt.NX + >>> set_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> set_param.ttl_second = 10 - >>> set_param.cache_type = yr.CacheType.DISK - >>> yr.kv_set("kv-key", b"value1", set_param) + >>> set_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_set("kv-key", b"value1", set_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ runtime_holder.global_runtime.get_runtime().kv_write(key, value, set_param) @@ -1004,7 +1004,7 @@ def kv_get( RuntimeError: If data retrieval from the data system fails. Example: - >>> v1 = yr.kv_get("kv-key") + >>> v1 = yuanrong.kv_get("kv-key") """ if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: raise ValueError( @@ -1040,12 +1040,12 @@ def kv_get_with_param(keys: List[str], get_params: GetParams, timeout: int = con RuntimeError: If data retrieval from the data system fails. Example: - >>> get_param = yr.GetParam() + >>> get_param = yuanrong.GetParam() >>> get_param.offset = 0 >>> get_param.size = 0 - >>> params = yr.GetParams() + >>> params = yuanrong.GetParams() >>> params.get_params = [get_param] - >>> v1 = yr.kv_get_with_param(["kv-key"], params, 10) + >>> v1 = yuanrong.kv_get_with_param(["kv-key"], params, 10) """ if timeout < constants.NO_LIMIT: raise ValueError( @@ -1074,8 +1074,8 @@ def kv_del(key: Union[str, List[str]]) -> None: RuntimeError: If data deletion from the data system fails. Example: - >>> yr.kv_write("kv-key", b"value1", yr.ExistenceOpt.NONE, yr.WriteMode.NONE_L2_CACHE, 0) # doctest: +SKIP - >>> yr.kv_del("kv-key") + >>> yuanrong.kv_write("kv-key", b"value1", yuanrong.ExistenceOpt.NONE, yuanrong.WriteMode.NONE_L2_CACHE, 0) # doctest: +SKIP + >>> yuanrong.kv_del("kv-key") """ runtime_holder.global_runtime.get_runtime().kv_del(key) @@ -1101,7 +1101,7 @@ def save_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: Example: - >>> @yr.instance + >>> @yuanrong.instance ... class Counter: ... def __init__(self): ... self.cnt = 0 @@ -1114,20 +1114,20 @@ def save_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: ... return self.cnt ... ... def save(self, timeout=30): - ... yr.save_state(timeout) + ... yuanrong.save_state(timeout) ... ... def load(self, timeout=30): - ... yr.load_state(timeout) + ... yuanrong.load_state(timeout) ... >>> counter = Counter.invoke() - >>> print(f"member value before save state: {yr.get(counter.get.invoke())}") + >>> print(f"member value before save state: {yuanrong.get(counter.get.invoke())}") >>> counter.save.invoke() >>> >>> counter.add.invoke() - >>> print(f"member value after add one: {yr.get(counter.get.invoke())}") + >>> print(f"member value after add one: {yuanrong.get(counter.get.invoke())}") >>> >>> counter.load.invoke() - >>> print(f"member value after load state(back to 0): {yr.get(counter.get.invoke())}") + >>> print(f"member value after load state(back to 0): {yuanrong.get(counter.get.invoke())}") """ remote_runtime = ConfigManager().in_cluster and not ConfigManager().is_driver if not remote_runtime: @@ -1163,7 +1163,7 @@ def load_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: Example: - >>> @yr.instance + >>> @yuanrong.instance ... class Counter: ... def __init__(self): ... self.cnt = 0 @@ -1176,22 +1176,22 @@ def load_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: ... return self.cnt ... ... def save(self, timeout=30): - ... yr.save_state(timeout) + ... yuanrong.save_state(timeout) ... ... def load(self, timeout=30): - ... yr.load_state(timeout) + ... yuanrong.load_state(timeout) ... >>> counter = Counter.invoke() - >>> print(f"member value before save state: {yr.get(counter.get.invoke())}") + >>> print(f"member value before save state: {yuanrong.get(counter.get.invoke())}") member value before save state: 0 >>> counter.save.invoke() >>> >>> counter.add.invoke() - >>> print(f"member value after add one: {yr.get(counter.get.invoke())}") + >>> print(f"member value after add one: {yuanrong.get(counter.get.invoke())}") member value after add one: 1 >>> >>> counter.load.invoke() - >>> print(f"member value after load state(back to 0): {yr.get(counter.get.invoke())}") + >>> print(f"member value after load state(back to 0): {yuanrong.get(counter.get.invoke())}") member value after load state(back to 0): 0 """ remote_runtime = ConfigManager().in_cluster and not ConfigManager().is_driver @@ -1226,7 +1226,7 @@ def get_instance(name: str, namespace: str = "", timeout: int = 60) -> instance_ TimeoutError: If a timeout occurs. Examples: - >>> yr.get_instance("name") + >>> yuanrong.get_instance("name") """ if not isinstance(name, str): @@ -1261,7 +1261,7 @@ def resources() -> List[dict]: """ Get the resource information of nodes in the cluster. - When requesting resource information, you need to configure `master_addr_list` in `yr.Config`. + When requesting resource information, you need to configure `master_addr_list` in `yuanrong.Config`. Returns: list[dict], The resource information of nodes in the cluster. The dict contains the following keys, @@ -1275,15 +1275,15 @@ def resources() -> List[dict]: RuntimeError: If the information retrieval from the functionsystem master fails. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> res = yr.resources() + >>> res = yuanrong.resources() >>> print(res) [{'id': 'function-agent-172.17.0.2-25742','status': 0, 'capacity': {'CPU': 1000.0, 'Memory': 8192.0}, 'allocatable': {'CPU': 500.0, 'Memory': 4096.0}}] >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if ConfigManager().local_mode: raise RuntimeError("resources is not supported in local mode") @@ -1295,11 +1295,11 @@ def get_node_ip_address(): """ Obtain the node ip. Examples: - >>> import yr - >>> yr.init() - >>> node_ip = yr.get_node_ip_address() + >>> import yuanrong + >>> yuanrong.init() + >>> node_ip = yuanrong.get_node_ip_address() >>> print(node_ip) - >>> yr.finalize() + >>> yuanrong.finalize() """ return runtime_holder.global_runtime.get_runtime().get_node_ip_address() @@ -1362,9 +1362,9 @@ def create_resource_group(bundles: List[Dict[str, float]], name: Optional[str] = RuntimeError: If the resource group name is invalid. Examples: - >>> rg1 = yr.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}]) + >>> rg1 = yuanrong.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}]) >>> - >>> rg2 = yr.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg2 = yuanrong.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}], "rgname") """ if not isinstance(bundles, list): raise TypeError(f"invalid bundles type, actual: {type(bundles)}, expect: list.") @@ -1394,10 +1394,10 @@ def remove_resource_group(resource_group: Union[str, ResourceGroup]): RuntimeError: The ResourceGroup name is invalid. Examples: - >>> yr.remove_resource_group("rgname") + >>> yuanrong.remove_resource_group("rgname") >>> - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") - >>> yr.remove_resource_group(rg) + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> yuanrong.remove_resource_group(rg) """ name = resource_group if isinstance(resource_group, ResourceGroup): @@ -1424,7 +1424,7 @@ class cpp_instance_class: .. code-block:: cpp #include - #include "yr/yr.h" + #include "yuanrong/yuanrong.h" class Counter { public: int count; @@ -1450,19 +1450,19 @@ class cpp_instance_class: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> cpp_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-cpp:$latest" + ... "function:0-yuanrong-defaultservice-cpp:$latest" ... ) - >>> counter_class = yr.cpp_instance_class("Counter", "Counter::FactoryCreate", cpp_function_urn) - >>> opt = yr.InvokeOptions(cpu=1000, memory=1024) + >>> counter_class = yuanrong.cpp_instance_class("Counter", "Counter::FactoryCreate", cpp_function_urn) + >>> opt = yuanrong.InvokeOptions(cpu=1000, memory=1024) >>> ins = counter_class.options(opt).invoke(11) >>> result = ins.Add.invoke(9) - >>> yr.get(result) + >>> yuanrong.get(result) >>> ins.terminate() - >>> yr.finalize() + >>> yuanrong.finalize() """ self.__class_name__ = class_name self.__factory_name__ = factory_name @@ -1531,7 +1531,7 @@ def cpp_function(function_name: str, function_urn: str) -> FunctionProxy: Examples: .. code-block:: cpp - #include "yr/yr.h" + #include "yuanrong/yuanrong.h" int Square(int x) { return x * x; @@ -1542,16 +1542,16 @@ def cpp_function(function_name: str, function_urn: str) -> FunctionProxy: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> cpp_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-cpp:$latest" + ... "function:0-yuanrong-defaultservice-cpp:$latest" ... ) - >>> square_func = yr.cpp_function("Square", cpp_function_urn) + >>> square_func = yuanrong.cpp_function("Square", cpp_function_urn) >>> result = square_func.invoke(5) - >>> print(yr.get(result)) - >>> yr.finalize() + >>> print(yuanrong.get(result)) + >>> yuanrong.finalize() """ return function_proxy.make_cross_language_function_proxy(function_name, function_urn, LanguageType.Cpp) @@ -1594,15 +1594,15 @@ def java_function(class_name: str, function_name: str, function_urn: str) -> Fun .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> java_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-java:$latest" + ... "function:0-yuanrong-defaultservice-java:$latest" ... ) - >>> java_add = yr.java_function("com.yuanrong.demo.PlusOne", "PlusOne", java_function_urn) + >>> java_add = yuanrong.java_function("com.yuanrong.demo.PlusOne", "PlusOne", java_function_urn) >>> result = java_add.invoke(1) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ function_key = utils.get_function_from_urn(function_urn) @@ -1650,22 +1650,22 @@ def java_instance_class(class_name: str, function_urn: str) -> InstanceCreator: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> java_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-java:$latest" + ... "function:0-yuanrong-defaultservice-java:$latest" ... ) >>> - >>> java_instance = yr.java_instance_class("com.yuanrong.demo.Counter", java_function_urn).invoke(1) + >>> java_instance = yuanrong.java_instance_class("com.yuanrong.demo.Counter", java_function_urn).invoke(1) >>> res = java_instance.Add.invoke(5) - >>> print(yr.get(res)) + >>> print(yuanrong.get(res)) >>> >>> res = java_instance.Get.invoke() - >>> print(yr.get(res)) + >>> print(yuanrong.get(res)) >>> >>> java_instance.terminate() - >>> yr.finalize() + >>> yuanrong.finalize() """ function_key = utils.get_function_from_urn(function_urn) @@ -1701,11 +1701,11 @@ def list_named_instances(all_namespaces: bool = False): If an instance is configured with a namespace, the namespace and instance name will be connected using a `-`. Examples: - >>> import yr - >>> yr.init() - >>> named_instances = yr.list_named_instances() + >>> import yuanrong + >>> yuanrong.init() + >>> named_instances = yuanrong.list_named_instances() >>> print(named_instances) - >>> yr.finalize() + >>> yuanrong.finalize() """ all_actors = runtime_holder.global_runtime.get_runtime().query_named_instances() if all_namespaces: diff --git a/api/python/yr/cluster_mode_runtime.py b/api/python/yuanrong/cluster_mode_runtime.py similarity index 96% rename from api/python/yr/cluster_mode_runtime.py rename to api/python/yuanrong/cluster_mode_runtime.py index f16d791..f81f5b3 100644 --- a/api/python/yr/cluster_mode_runtime.py +++ b/api/python/yuanrong/cluster_mode_runtime.py @@ -19,19 +19,19 @@ import logging from typing import Any, Dict, List, Tuple, Union, Callable -from yr.exception import YRInvokeError -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.common.types import InvokeArg, GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.config_manager import ConfigManager -from yr.fnruntime import Consumer, Fnruntime, Producer, SharedBuffer -from yr.libruntime_pb2 import ApiType, FunctionMeta -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData -from yr.object_ref import ObjectRef -from yr.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams -from yr.serialization import Serialization -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.accelerate.shm_broadcast import Handle +from yuanrong.exception import YRInvokeError +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.common.types import InvokeArg, GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.fnruntime import Consumer, Fnruntime, Producer, SharedBuffer +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.serialization import Serialization +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.accelerate.shm_broadcast import Handle _logger = logging.getLogger(__name__) diff --git a/api/python/yr/code_manager.py b/api/python/yuanrong/code_manager.py similarity index 97% rename from api/python/yr/code_manager.py rename to api/python/yuanrong/code_manager.py index c85afed..74b20e9 100644 --- a/api/python/yr/code_manager.py +++ b/api/python/yuanrong/code_manager.py @@ -23,12 +23,12 @@ import sys import threading from typing import Callable, List -from yr import log -from yr.common import constants, utils -from yr.common.singleton import Singleton -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.functionsdk.error_code import FaasErrorCode -from yr.libruntime_pb2 import LanguageType +from yuanrong import log +from yuanrong.common import constants, utils +from yuanrong.common.singleton import Singleton +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.functionsdk.error_code import FaasErrorCode +from yuanrong.libruntime_pb2 import LanguageType _DEFAULT_ADMIN_FUNC_PATH = "/adminfunc/" _MAX_FAAS_ENTRY_NUMS = 3 diff --git a/api/python/yr/common/__init__.py b/api/python/yuanrong/common/__init__.py similarity index 100% rename from api/python/yr/common/__init__.py rename to api/python/yuanrong/common/__init__.py diff --git a/api/python/yr/common/constants.py b/api/python/yuanrong/common/constants.py similarity index 100% rename from api/python/yr/common/constants.py rename to api/python/yuanrong/common/constants.py diff --git a/api/python/yr/common/singleton.py b/api/python/yuanrong/common/singleton.py similarity index 100% rename from api/python/yr/common/singleton.py rename to api/python/yuanrong/common/singleton.py diff --git a/api/python/yr/common/types.py b/api/python/yuanrong/common/types.py similarity index 100% rename from api/python/yr/common/types.py rename to api/python/yuanrong/common/types.py diff --git a/api/python/yr/common/utils.py b/api/python/yuanrong/common/utils.py similarity index 99% rename from api/python/yr/common/utils.py rename to api/python/yuanrong/common/utils.py index e67a6a2..cd931a2 100644 --- a/api/python/yr/common/utils.py +++ b/api/python/yuanrong/common/utils.py @@ -33,9 +33,9 @@ from typing import Dict import asyncio import cloudpickle -from yr import log -from yr.common import constants -from yr.libruntime_pb2 import LanguageType, FunctionMeta +from yuanrong import log +from yuanrong.common import constants +from yuanrong.libruntime_pb2 import LanguageType, FunctionMeta try: import uvloop @@ -45,7 +45,7 @@ except ImportError: _URN_SEPARATOR = ":" _NO_ORDER_SUFFIX = "-x" -_OBJECT_ID_PREFIX = "yr-api-obj-" +_OBJECT_ID_PREFIX = "yuanrong-api-obj-" _TRACE_ID = "-trace-" _JOB_ID = "" _RGROUP_PREFIX = "rgroup-" diff --git a/api/python/yr/compiled_dag_ref.py b/api/python/yuanrong/compiled_dag_ref.py similarity index 92% rename from api/python/yr/compiled_dag_ref.py rename to api/python/yuanrong/compiled_dag_ref.py index 6893416..c69321f 100644 --- a/api/python/yr/compiled_dag_ref.py +++ b/api/python/yuanrong/compiled_dag_ref.py @@ -17,8 +17,8 @@ import asyncio from typing import Any, List, Optional -import yr -from yr.exception import ( +import yuanrong +from yuanrong.exception import ( GetTimeoutError, YRChannelError, YRChannelTimeoutError, @@ -54,17 +54,17 @@ class CompiledDAGRef: A reference to a compiled DAG execution result. This is a subclass of ObjectRef and resembles ObjectRef. For example, - similar to ObjectRef, yr.get() can be called on it to retrieve the result. + similar to ObjectRef, yuanrong.get() can be called on it to retrieve the result. However, there are several major differences: - 1. yr.get() can only be called once per CompiledDAGRef. - 2. yr.wait() is not supported. + 1. yuanrong.get() can only be called once per CompiledDAGRef. + 2. yuanrong.wait() is not supported. 3. CompiledDAGRef cannot be copied, deep copied, or pickled. 4. CompiledDAGRef cannot be passed as an argument to another task. """ def __init__( self, - dag: "yr.dag.CompiledDAG", + dag: "yuanrong.dag.CompiledDAG", execution_index: int, channel_index: Optional[int] = None, ): @@ -87,7 +87,7 @@ class CompiledDAGRef: self._dag = dag self._execution_index = execution_index self._channel_index = channel_index - # Whether yr.get() was called on this CompiledDAGRef. + # Whether yuanrong.get() was called on this CompiledDAGRef. self._yr_get_called = False self._dag_output_channels = dag.dag_output_channels @@ -116,7 +116,7 @@ class CompiledDAGRef: """ if self._yr_get_called: raise ValueError( - "yr.get() can only be called once " + "yuanrong.get() can only be called once " "on a CompiledDAGRef, and it was already called." ) @@ -131,7 +131,7 @@ class CompiledDAGRef: except YRChannelTimeoutError: raise except YRChannelError: - # If we get a channel error, we'd like to call yr.get() on + # If we get a channel error, we'd like to call yuanrong.get() on # the actor execution loop refs to check if this is a result # of task execution error which could not be passed down # (e.g., when a pure NCCL channel is used, it is only @@ -142,7 +142,7 @@ class CompiledDAGRef: # actor task refs have errors. actor_execution_loop_refs = list(self._dag.worker_task_refs.values()) try: - yr.get(actor_execution_loop_refs, timeout=10) + yuanrong.get(actor_execution_loop_refs, timeout=10) except GetTimeoutError as timeout_error: raise Exception( "Timed out when getting the actor execution loop exception. " @@ -161,20 +161,20 @@ class CompiledDAGFuture: """ A reference to a compiled DAG execution result, when executed with asyncio. This differs from CompiledDAGRef in that `await` must be called on the - future to get the result, instead of `yr.get()`. + future to get the result, instead of `yuanrong.get()`. This resembles async usage of ObjectRefs. For example, similar to ObjectRef, `await` can be called directly on the CompiledDAGFuture to retrieve the result. However, there are several major differences: 1. `await` can only be called once per CompiledDAGFuture. - 2. yr.wait() is not supported. + 2. yuanrong.wait() is not supported. 3. CompiledDAGFuture cannot be copied, deep copied, or pickled. 4. CompiledDAGFuture cannot be passed as an argument to another task. """ def __init__( self, - dag: "yr.dag.CompiledDAG", + dag: "yuanrong.dag.CompiledDAG", execution_index: int, fut: "asyncio.Future", channel_index: Optional[int] = None, diff --git a/api/python/yr/config.py b/api/python/yuanrong/config.py similarity index 96% rename from api/python/yr/config.py rename to api/python/yuanrong/config.py index 1b73779..dae788f 100644 --- a/api/python/yr/config.py +++ b/api/python/yuanrong/config.py @@ -15,14 +15,14 @@ # limitations under the License. """ -yr api config for user +yuanrong api config for user """ import dataclasses import json from dataclasses import asdict, dataclass, field from typing import Dict, List, Union, Optional, get_origin, Any from enum import Enum, IntEnum -from yr.affinity import Affinity +from yuanrong.affinity import Affinity _DEFAULT_CONNECTION_NUMS = 100 _DEFAULT_ENABLE_METRICS = False @@ -113,7 +113,7 @@ class Config: job_id: str = "" #: For out cluster https ssl. tls_config: UserTLSConfig = None - #: Auto start distribute-executor when `yr.init`, and auto stop distribute-executor when `yr.finalize`. + #: Auto start distribute-executor when `yuanrong.init`, and auto stop distribute-executor when `yuanrong.finalize`. #: default is ``False``. auto: bool = False #: When `auto=True` needed, use to define deployment detail. @@ -190,9 +190,9 @@ class Config: @dataclass class ClientInfo: """ - Use to store yr client info. + Use to store yuanrong client info. """ - #: Automatically generated when `yr.init` is called, a unique identifier for a task. + #: Automatically generated when `yuanrong.init` is called, a unique identifier for a task. job_id: str @@ -332,17 +332,17 @@ class InvokeOptions: """Use to set the invoke options. Examples: - >>> import yr + >>> import yuanrong >>> import time - >>> yr.init() - >>> opt = yr.InvokeOptions() + >>> yuanrong.init() + >>> opt = yuanrong.InvokeOptions() >>> opt.pod_labels["k1"] = "v1" - >>> @yr.invoke(invoke_options=opt) + >>> @yuanrong.invoke(invoke_options=opt) ... def func(): ... time.sleep(100) >>> ret = func.invoke() - >>> yr.get(ret) - >>> yr.finalize() + >>> yuanrong.get(ret) + >>> yuanrong.finalize() """ #: The size of the CPU required. Value Range is [300, 16000] and unit is m (milli-core). cpu: int = 500 @@ -384,9 +384,9 @@ class InvokeOptions: When used as a user-defined tag for metrics: - >>> import yr - >>> yr.init() - >>> opt = yr.InvokeOptions() + >>> import yuanrong + >>> yuanrong.init() + >>> opt = yuanrong.InvokeOptions() >>> opt.custom_extensions["YR_Metrics"] = "{\'endpoint\':\'127.0.0.1\', \'project_id\':\'my_project_id\'}" In Prometheus, select `metrics name` as `yr_app_instance_billing_invoke_latency`, and you can find the custom tag @@ -517,18 +517,18 @@ class InvokeOptions: * `working_dir` configure the code path of the job. * `env_vars` configure process-level environment variables. ``runtime_env = {"env_vars":{"OMP_NUM_THREADS": "32", "TF_WARNINGS": "none"}}`` - * `shared_dir` supports configuring a shared directory for some instance, with yr managing the lifecycle of this + * `shared_dir` supports configuring a shared directory for some instance, with yuanrong managing the lifecycle of this shared directory. `shared_dir` supports two fields: name and TTL. The name field only allows numbers, letters, "-", and "_". The TTL supports integers greater than 0 and less than INTMAX. ``runtime_env = {"shared_dir":{"name": "user_define", "TTL": 5}}`` * Constraints of `runtime_env`: * The keys supported by runtime_env are `conda`, `env_vars`, `pip`, `working_dir`. Other keys will not take effect and will not cause errors. - * Run the yr function with conda. The environment needs to have yr and its third-party dependencies. It is + * Run the yuanrong function with conda. The environment needs to have yuanrong and its third-party dependencies. It is recommended that users first create a conda environment and then specify it with `runtime_env`, for example: ``runtime_env = {"conda":"pytorch_p39"}`` * `runtime_env` supports creating and switching conda environments using configurations. The configuration needs - to install third-party dependencies for yr, for example: + to install third-party dependencies for yuanrong, for example: ``runtime_env["conda"] = {"name":"myenv","channels": ["conda-forge"], "dependencies": ["python=3.9", "msgpack-python=1.0.5", "protobuf", "libgcc-ng", "cloudpickle=2.0.0", "cython=3.0.10", "pyyaml=6.0.2"]}`` * The environment created using conda in `runtime_env` needs to be cleaned up by the user. @@ -545,7 +545,7 @@ class InvokeOptions: * `shared_dir` has the following constraints: 1. It is not recommended to configure different TTL for the same shared directory. 2. The minimum cleanup interval for shared directories is 5 seconds. - 3. When multiple yr Agents are deployed on the same node, each Agent must be configured with + 3. When multiple yuanrong Agents are deployed on the same node, each Agent must be configured with different root directory to prevent conflicts in shared directory management. """ diff --git a/api/python/yr/config/python-runtime-log.json b/api/python/yuanrong/config/python-runtime-log.json similarity index 100% rename from api/python/yr/config/python-runtime-log.json rename to api/python/yuanrong/config/python-runtime-log.json diff --git a/api/python/yr/config_manager.py b/api/python/yuanrong/config_manager.py similarity index 97% rename from api/python/yr/config_manager.py rename to api/python/yuanrong/config_manager.py index 186c517..1154415 100644 --- a/api/python/yr/config_manager.py +++ b/api/python/yuanrong/config_manager.py @@ -18,9 +18,9 @@ import logging -from yr.common import utils -from yr.common.singleton import Singleton -from yr.config import Config, DeploymentConfig, MetaConfig, MetaFunctionID +from yuanrong.common import utils +from yuanrong.common.singleton import Singleton +from yuanrong.config import Config, DeploymentConfig, MetaConfig, MetaFunctionID _DEFAULT_CLUSTER_PORT = "31222" _DEFAULT_IN_CLUSTER_CLUSTER_PORT = "21003" @@ -51,7 +51,7 @@ class ConfigManager: server_address: System cluster address. ds_address: DataSystem address. is_driver: only False when initialize in runtime - log_level: yr api log level, default: WARNING + log_level: yuanrong api log level, default: WARNING """ def __init__(self): @@ -230,7 +230,7 @@ class ConfigManager: Init the ConfigManager Args: - :param conf: The yr api config which set by user. + :param conf: The yuanrong api config which set by user. :param is_init: init state """ job_id = conf.job_id if conf.job_id != "" else utils.generate_job_id() diff --git a/api/python/yr/decorator/__init__.py b/api/python/yuanrong/decorator/__init__.py similarity index 100% rename from api/python/yr/decorator/__init__.py rename to api/python/yuanrong/decorator/__init__.py diff --git a/api/python/yr/decorator/function_proxy.py b/api/python/yuanrong/decorator/function_proxy.py similarity index 90% rename from api/python/yr/decorator/function_proxy.py rename to api/python/yuanrong/decorator/function_proxy.py index c2049cc..5f977a5 100644 --- a/api/python/yr/decorator/function_proxy.py +++ b/api/python/yuanrong/decorator/function_proxy.py @@ -24,17 +24,17 @@ import types from functools import wraps from typing import List, Union -import yr -from yr import signature -from yr.config import function_group_enabled -from yr.common.types import GroupInfo -from yr.common import utils -from yr.common.utils import CrossLanguageInfo, ObjectDescriptor -from yr.config import InvokeOptions -from yr.libruntime_pb2 import FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.generator import ObjectRefGenerator +import yuanrong +from yuanrong import signature +from yuanrong.config import function_group_enabled +from yuanrong.common.types import GroupInfo +from yuanrong.common import utils +from yuanrong.common.utils import CrossLanguageInfo, ObjectDescriptor +from yuanrong.config import InvokeOptions +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.generator import ObjectRefGenerator _logger = logging.getLogger(__name__) @@ -44,18 +44,18 @@ class FunctionProxy: Use to decorate user function. Examples: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> >>> ret = add.invoke(1, 2) - >>> print(yr.get(ret)) + >>> print(yuanrong.get(ret)) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ def __init__(self, func, cross_language_info=None, invoke_options=None, return_nums=None, initializer=None): @@ -141,19 +141,19 @@ class FunctionProxy: The FunctionProxy object itself. Data type is FunctionProxy. Examples: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> - >>> opt = yr.InvokeOptions(cpu=1000, memory=1024) + >>> opt = yuanrong.InvokeOptions(cpu=1000, memory=1024) >>> ret = add.options(opt).invoke(1, 2) - >>> print(yr.get(ret)) + >>> print(yuanrong.get(ret)) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ for method in ("check_options_valid", "check_options_range"): @@ -210,7 +210,7 @@ class FunctionProxy: return self._options_wrapper(opts) def _invoke_function(self, opts: InvokeOptions, func, args=None, kwargs=None) -> Union[ - "yr.ObjectRef", List["yr.ObjectRef"]]: + "yuanrong.ObjectRef", List["yuanrong.ObjectRef"]]: """ The real realization of the invoke function @@ -232,12 +232,12 @@ class FunctionProxy: or not global_runtime.get_runtime().is_object_existing_in_local( self._code_ref.id )): - self._code_ref = yr.put(func) + self._code_ref = yuanrong.put(func) _logger.debug("[Reference Counting] put code with id = %s, functionName = %s", self._code_ref.id, func.__qualname__) with self._lock: if self._initializer and self._initializer_code_ref is None: - self._initializer_code_ref = yr.put(self._initializer) + self._initializer_code_ref = yuanrong.put(self._initializer) initializer_code_id = self._initializer_code_ref if self._initializer_code_ref is not None else "" func_meta = FunctionMeta(functionID=function_id, # if designated_urn is not set, @@ -305,7 +305,7 @@ def make_decorator(invoke_options=None, return_nums=None, initializer=None) -> c def decorator(func): if isinstance(func, types.FunctionType): return FunctionProxy(func, invoke_options=invoke_options, return_nums=return_nums, initializer=initializer) - raise RuntimeError("@yr.invoke decorator must be applied to a function") + raise RuntimeError("@yuanrong.invoke decorator must be applied to a function") return decorator diff --git a/api/python/yr/decorator/instance_proxy.py b/api/python/yuanrong/decorator/instance_proxy.py similarity index 96% rename from api/python/yr/decorator/instance_proxy.py rename to api/python/yuanrong/decorator/instance_proxy.py index 42ea8fe..f277f33 100644 --- a/api/python/yr/decorator/instance_proxy.py +++ b/api/python/yuanrong/decorator/instance_proxy.py @@ -25,18 +25,18 @@ import threading import weakref import uuid from typing import List -import yr -from yr import signature -from yr.code_manager import CodeManager -from yr.generator import ObjectRefGenerator -from yr.common import constants, utils -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, function_group_enabled -from yr.libruntime_pb2 import FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime, save_real_instance_id -from yr.serialization import register_pack_hook, register_unpack_hook -from yr.accelerate.shm_broadcast import MessageQueue, STOP_EVENT +import yuanrong +from yuanrong import signature +from yuanrong.code_manager import CodeManager +from yuanrong.generator import ObjectRefGenerator +from yuanrong.common import constants, utils +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, function_group_enabled +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime, save_real_instance_id +from yuanrong.serialization import register_pack_hook, register_unpack_hook +from yuanrong.accelerate.shm_broadcast import MessageQueue, STOP_EVENT _logger = logging.getLogger(__name__) @@ -253,7 +253,7 @@ class InstanceCreator: self._code_ref is None or not global_runtime.get_runtime().is_object_existing_in_local(self._code_ref.id) ): - self._code_ref = yr.put(self.__user_class__) + self._code_ref = yuanrong.put(self.__user_class__) _logger.info("[Reference Counting] put code with id = %s, className = %s", self._code_ref.id, self.__user_class_descriptor__.class_name) # __init__ existed when user-defined @@ -601,7 +601,7 @@ class MethodProxy: raise RuntimeError(f"invalid return_nums: {return_nums}, should be an integer between 0 and 100") - def invoke(self, *args, **kwargs) -> "yr.ObjectRef": + def invoke(self, *args, **kwargs) -> "yuanrong.ObjectRef": """ Execute remote invoke to user functions. @@ -616,10 +616,10 @@ class MethodProxy: TypeError: If the parameter type is incorrect. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... @@ -630,13 +630,13 @@ class MethodProxy: ... return self.sum ... >>> ins = Instance.invoke() - >>> yr.get(ins.add.invoke(1)) + >>> yuanrong.get(ins.add.invoke(1)) >>> - >>> print(yr.get(ins.get.invoke())) + >>> print(yuanrong.get(ins.get.invoke())) >>> >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ return self._invoke(args, kwargs) @@ -708,7 +708,7 @@ def make_decorator(invoke_options=None): def decorator(cls): if inspect.isclass(cls): return InstanceCreator.create_from_user_class(cls, invoke_options) - raise RuntimeError("@yr.instance decorator must be applied to a class") + raise RuntimeError("@yuanrong.instance decorator must be applied to a class") return decorator diff --git a/api/python/yr/device.py b/api/python/yuanrong/device.py similarity index 97% rename from api/python/yr/device.py rename to api/python/yuanrong/device.py index 67080c2..5897d50 100644 --- a/api/python/yr/device.py +++ b/api/python/yuanrong/device.py @@ -17,8 +17,8 @@ """device providing device buffer function.""" from enum import Enum from typing import List -from yr import runtime_holder -from yr.common.utils import Validator as validator +from yuanrong import runtime_holder +from yuanrong.common.utils import Validator as validator class DataType(Enum): diff --git a/api/python/yr/err_type.py b/api/python/yuanrong/err_type.py similarity index 100% rename from api/python/yr/err_type.py rename to api/python/yuanrong/err_type.py diff --git a/api/python/yr/exception.py b/api/python/yuanrong/exception.py similarity index 97% rename from api/python/yr/exception.py rename to api/python/yuanrong/exception.py index df571dc..2b4bd68 100644 --- a/api/python/yr/exception.py +++ b/api/python/yuanrong/exception.py @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""yr exception type""" +"""yuanrong exception type""" import cloudpickle -from yr.common import utils +from yuanrong.common import utils class YRError(Exception): @@ -142,7 +142,7 @@ class GetTimeoutError(YRError, TimeoutError): class YRChannelError(YRError): """Indicates that encountered a system error related - to yr.dag.channel. + to yuanrong.dag.channel. """ pass @@ -170,7 +170,7 @@ class GeneratorFinished(Exception): def deal_with_yr_error(future, err): - """deal with yr invoke error""" + """deal with yuanrong invoke error""" if isinstance(err, YRInvokeError): future.set_exception(err.origin_error()) else: diff --git a/api/python/yr/executor/__init__.py b/api/python/yuanrong/executor/__init__.py similarity index 100% rename from api/python/yr/executor/__init__.py rename to api/python/yuanrong/executor/__init__.py diff --git a/api/python/yr/executor/executor.py b/api/python/yuanrong/executor/executor.py similarity index 89% rename from api/python/yr/executor/executor.py rename to api/python/yuanrong/executor/executor.py index eff61b0..c36e9a7 100644 --- a/api/python/yr/executor/executor.py +++ b/api/python/yuanrong/executor/executor.py @@ -19,14 +19,14 @@ import threading from typing import List, Tuple -from yr import log -from yr.common.utils import get_environment_variable -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.executor.function_handler import FunctionHandler -from yr.executor.faas_executor import faas_call_handler, faas_init_handler -from yr.executor.faas_handler import FaasHandler -from yr.executor.posix_handler import PosixHandler -from yr.libruntime_pb2 import ApiType, InvokeType +from yuanrong import log +from yuanrong.common.utils import get_environment_variable +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.executor.faas_executor import faas_call_handler, faas_init_handler +from yuanrong.executor.faas_handler import FaasHandler +from yuanrong.executor.posix_handler import PosixHandler +from yuanrong.libruntime_pb2 import ApiType, InvokeType HANDLER = None _LOCK = threading.Lock() diff --git a/api/python/yr/executor/faas_executor.py b/api/python/yuanrong/executor/faas_executor.py similarity index 94% rename from api/python/yr/executor/faas_executor.py rename to api/python/yuanrong/executor/faas_executor.py index 0863774..2a6fa55 100644 --- a/api/python/yr/executor/faas_executor.py +++ b/api/python/yuanrong/executor/faas_executor.py @@ -22,17 +22,17 @@ import traceback import queue from typing import Any, List -from yr.code_manager import CodeManager -from yr.common.utils import to_json_string -from yr.err_type import ErrorInfo, ModuleCode, ErrorCode -from yr.functionsdk.utils import encode_base64, timeout +from yuanrong.code_manager import CodeManager +from yuanrong.common.utils import to_json_string +from yuanrong.err_type import ErrorInfo, ModuleCode, ErrorCode +from yuanrong.functionsdk.utils import encode_base64, timeout -from yr import log -from yr.common import constants -from yr.common.constants import META_PREFIX, METALEN -from yr.functionsdk.context import init_context, init_context_invoke, load_context_meta -from yr.functionsdk.logger_manager import UserLogManager -from yr.functionsdk.error_code import FaasErrorCode +from yuanrong import log +from yuanrong.common import constants +from yuanrong.common.constants import META_PREFIX, METALEN +from yuanrong.functionsdk.context import init_context, init_context_invoke, load_context_meta +from yuanrong.functionsdk.logger_manager import UserLogManager +from yuanrong.functionsdk.error_code import FaasErrorCode _STAGE_INIT = "init" _STAGE_INVOKE = "invoke" diff --git a/api/python/yr/executor/faas_handler.py b/api/python/yuanrong/executor/faas_handler.py similarity index 83% rename from api/python/yr/executor/faas_handler.py rename to api/python/yuanrong/executor/faas_handler.py index 9fae2a0..6eeadc7 100644 --- a/api/python/yr/executor/faas_handler.py +++ b/api/python/yuanrong/executor/faas_handler.py @@ -18,11 +18,11 @@ from typing import List -from yr import log -from yr.common.utils import err_to_str -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.executor.faas_executor import faas_shutdown_handler -from yr.executor.handler_intf import HandlerIntf +from yuanrong import log +from yuanrong.common.utils import err_to_str +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.executor.faas_executor import faas_shutdown_handler +from yuanrong.executor.handler_intf import HandlerIntf class FaasHandler(HandlerIntf): diff --git a/api/python/yr/executor/function_handler.py b/api/python/yuanrong/executor/function_handler.py similarity index 92% rename from api/python/yr/executor/function_handler.py rename to api/python/yuanrong/executor/function_handler.py index 897f896..4658dc4 100644 --- a/api/python/yr/executor/function_handler.py +++ b/api/python/yuanrong/executor/function_handler.py @@ -20,17 +20,17 @@ import traceback import inspect from typing import List, Tuple -from yr.libruntime_pb2 import InvokeType - -import yr -from yr import log -from yr.code_manager import CodeManager -from yr.common.utils import err_to_str -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.exception import YRInvokeError -from yr.executor.handler_intf import HandlerIntf -from yr.executor.instance_manager import InstanceManager -from yr.signature import recover_args +from yuanrong.libruntime_pb2 import InvokeType + +import yuanrong +from yuanrong import log +from yuanrong.code_manager import CodeManager +from yuanrong.common.utils import err_to_str +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.exception import YRInvokeError +from yuanrong.executor.handler_intf import HandlerIntf +from yuanrong.executor.instance_manager import InstanceManager +from yuanrong.signature import recover_args USER_SHUTDOWN_FUNC_NAME = "__yr_shutdown__" @@ -155,7 +155,7 @@ class FunctionHandler(HandlerIntf): return result def __get_param(self, args: List) -> Tuple[object, object]: - params = yr.serialization.Serialization().deserialize(args) + params = yuanrong.serialization.Serialization().deserialize(args) args, kwargs = recover_args(params) return args, kwargs diff --git a/api/python/yr/executor/handler_intf.py b/api/python/yuanrong/executor/handler_intf.py similarity index 97% rename from api/python/yr/executor/handler_intf.py rename to api/python/yuanrong/executor/handler_intf.py index 2c18f59..e74f510 100644 --- a/api/python/yr/executor/handler_intf.py +++ b/api/python/yuanrong/executor/handler_intf.py @@ -19,7 +19,7 @@ from abc import ABC, abstractmethod from typing import List -from yr.err_type import ErrorInfo +from yuanrong.err_type import ErrorInfo class HandlerIntf(ABC): diff --git a/api/python/yr/executor/instance_manager.py b/api/python/yuanrong/executor/instance_manager.py similarity index 97% rename from api/python/yr/executor/instance_manager.py rename to api/python/yuanrong/executor/instance_manager.py index 72d9600..0d7ce0a 100644 --- a/api/python/yr/executor/instance_manager.py +++ b/api/python/yuanrong/executor/instance_manager.py @@ -16,8 +16,8 @@ """instance manager""" -from yr.common.singleton import Singleton -from yr.object_ref import ObjectRef +from yuanrong.common.singleton import Singleton +from yuanrong.object_ref import ObjectRef @Singleton diff --git a/api/python/yr/executor/posix_handler.py b/api/python/yuanrong/executor/posix_handler.py similarity index 95% rename from api/python/yr/executor/posix_handler.py rename to api/python/yuanrong/executor/posix_handler.py index c26319e..95d9967 100644 --- a/api/python/yr/executor/posix_handler.py +++ b/api/python/yuanrong/executor/posix_handler.py @@ -18,7 +18,7 @@ from typing import List -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode class PosixHandler: diff --git a/api/python/yr/fcc.py b/api/python/yuanrong/fcc.py similarity index 80% rename from api/python/yr/fcc.py rename to api/python/yuanrong/fcc.py index 3e568e3..da65ca1 100644 --- a/api/python/yr/fcc.py +++ b/api/python/yuanrong/fcc.py @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Union, List -from yr.config import FunctionGroupOptions, FunctionGroupContext -from yr.decorator import function_proxy, instance_proxy -from yr.runtime_holder import global_runtime -import yr +from yuanrong.config import FunctionGroupOptions, FunctionGroupContext +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.runtime_holder import global_runtime +import yuanrong def create_function_group( @@ -25,7 +25,7 @@ def create_function_group( args: tuple, group_size: int, options: FunctionGroupOptions, -) -> Union[List["yr.ObjectRef"], instance_proxy.FunctionGroupHandler]: +) -> Union[List["yuanrong.ObjectRef"], instance_proxy.FunctionGroupHandler]: """ Create function group instance. @@ -53,19 +53,19 @@ def create_function_group( Raises: ValueError: If the `FunctionGroupOptions` or `group_size` parameter is incorrectly filled, this exception will be thrown. - RuntimeError: If function is not wrapped by `@yr.invoke` or `@yr.instance`, this exception will be thrown. + RuntimeError: If function is not wrapped by `@yuanrong.invoke` or `@yuanrong.instance`, this exception will be thrown. Examples: stateless function invoke example: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo_func(name): ... return name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -74,15 +74,15 @@ def create_function_group( ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "function_demo" - >>> objs = yr.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) - >>> rets = yr.get(objs) + >>> objs = yuanrong.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) + >>> rets = yuanrong.get(objs) >>> assert rets == [name for i in range(1, 9)] - >>> yr.finalize() + >>> yuanrong.finalize() class invoke example: - >>> import yr + >>> import yuanrong >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Demo(object): ... name = "" >>> @@ -92,7 +92,7 @@ def create_function_group( >>> def return_name(self): ... return self.name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -101,13 +101,13 @@ def create_function_group( ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "class_demo" - >>> function_group_handler = yr.fcc.create_function_group(Demo, args=(name, ), group_size=8, options=opts) + >>> function_group_handler = yuanrong.fcc.create_function_group(Demo, args=(name, ), group_size=8, options=opts) >>> objs = function_group_handler.return_name.invoke() - >>> results = yr.get(objs) + >>> results = yuanrong.get(objs) >>> assert results == [name for i in range(1, 9)] >>> function_group_handler.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ bundle_size = options.scheduling_affinity_each_bundle_size if bundle_size is None or bundle_size <= 0: @@ -123,7 +123,7 @@ def create_function_group( options.timeout = -1 if options.timeout != -1 and options.timeout < 0 or options.timeout > 0x7FFFFFFF: raise ValueError(f"invalid timeout {options.timeout} in FunctionGroupOptions, expect:-1, [0, 0x7FFFFFFF]") - opts = yr.InvokeOptions() + opts = yuanrong.InvokeOptions() opts.function_group_options = options opts.cpu = opts.cpu if options.cpu is None else options.cpu opts.memory = opts.memory if options.memory is None else options.memory @@ -136,7 +136,7 @@ def create_function_group( return proxy.get_function_group_handler() if isinstance(wrapper, function_proxy.FunctionProxy): return wrapper.options(opts).set_function_group_size(group_size).invoke(*args) - raise RuntimeError("function is not wrapped by @yr.invoke or @yr.instance") + raise RuntimeError("function is not wrapped by @yuanrong.invoke or @yuanrong.instance") def get_function_group_context() -> FunctionGroupContext: @@ -153,16 +153,16 @@ def get_function_group_context() -> FunctionGroupContext: The function group context, i.e., FunctionGroupContext. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo_func(name): - ... context = yr.fcc.get_function_group_context() + ... context = yuanrong.fcc.get_function_group_context() ... print(context) ... return name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -171,9 +171,9 @@ def get_function_group_context() -> FunctionGroupContext: ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "function_demo" - >>> objs = yr.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) - >>> rets = yr.get(objs) + >>> objs = yuanrong.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) + >>> rets = yuanrong.get(objs) >>> assert rets == [name for i in range(1, 9)] - >>> yr.finalize() + >>> yuanrong.finalize() """ return global_runtime.get_runtime().get_function_group_context() diff --git a/api/python/yr/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx similarity index 100% rename from api/python/yr/fnruntime.pyx rename to api/python/yuanrong/fnruntime.pyx diff --git a/api/python/yr/functionsdk/__init__.py b/api/python/yuanrong/functionsdk/__init__.py similarity index 100% rename from api/python/yr/functionsdk/__init__.py rename to api/python/yuanrong/functionsdk/__init__.py diff --git a/api/python/yr/functionsdk/context.py b/api/python/yuanrong/functionsdk/context.py similarity index 99% rename from api/python/yr/functionsdk/context.py rename to api/python/yuanrong/functionsdk/context.py index 0f3646c..410a6d0 100644 --- a/api/python/yr/functionsdk/context.py +++ b/api/python/yuanrong/functionsdk/context.py @@ -22,9 +22,9 @@ import os import time from typing import Any, Dict -from yr import log -from yr.common import constants -from yr.functionsdk.utils import parse_json_data_to_dict, dump_data_to_json_str +from yuanrong import log +from yuanrong.common import constants +from yuanrong.functionsdk.utils import parse_json_data_to_dict, dump_data_to_json_str _RUNTIME_MAX_RESP_BODY_SIZE = 6 * 1024 * 1024 _RUNTIME_CODE_ROOT = "/opt/function/code" diff --git a/api/python/yr/functionsdk/error_code.py b/api/python/yuanrong/functionsdk/error_code.py similarity index 100% rename from api/python/yr/functionsdk/error_code.py rename to api/python/yuanrong/functionsdk/error_code.py diff --git a/api/python/yr/functionsdk/function.py b/api/python/yuanrong/functionsdk/function.py similarity index 96% rename from api/python/yr/functionsdk/function.py rename to api/python/yuanrong/functionsdk/function.py index 13df03c..d41d4c2 100644 --- a/api/python/yr/functionsdk/function.py +++ b/api/python/yuanrong/functionsdk/function.py @@ -22,14 +22,14 @@ import os import re from typing import Tuple, Union, Dict, List -from yr import log -from yr.config import InvokeOptions as YRInvokeOptions -from yr.common import constants -from yr.common.constants import META_PREFIX -from yr.libruntime_pb2 import ApiType, FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.functionsdk.context import Context +from yuanrong import log +from yuanrong.config import InvokeOptions as YRInvokeOptions +from yuanrong.common import constants +from yuanrong.common.constants import META_PREFIX +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.functionsdk.context import Context DEFAULT_FUNCTION_VERSION = "latest" DEFAULT_INVOKE_TIMEOUT = 900 @@ -288,7 +288,7 @@ def _check_reg_length(name: str, pattern: str, length_limit: int): def _convert_invoke_options(options: InvokeOptions, context: Context) -> YRInvokeOptions: - """convert invoke options to yr options""" + """convert invoke options to yuanrong options""" if options.concurrency == 0: options.concurrency = 100 yr_options = YRInvokeOptions() diff --git a/api/python/yr/functionsdk/logger.py b/api/python/yuanrong/functionsdk/logger.py similarity index 98% rename from api/python/yr/functionsdk/logger.py rename to api/python/yuanrong/functionsdk/logger.py index 4b750f6..8f2a586 100644 --- a/api/python/yr/functionsdk/logger.py +++ b/api/python/yuanrong/functionsdk/logger.py @@ -22,7 +22,7 @@ import logging.handlers import os import shutil -from yr.log import CustomFilter, RuntimeLogger +from yuanrong.log import CustomFilter, RuntimeLogger LOG_DEFAULT_MAX_BYTES = 50 * 1024 * 1024 LOG_DEFAULT_BACKUP_COUNT = 3 diff --git a/api/python/yr/functionsdk/logger_manager.py b/api/python/yuanrong/functionsdk/logger_manager.py similarity index 98% rename from api/python/yr/functionsdk/logger_manager.py rename to api/python/yuanrong/functionsdk/logger_manager.py index a6b8a5a..2729c9d 100644 --- a/api/python/yr/functionsdk/logger_manager.py +++ b/api/python/yuanrong/functionsdk/logger_manager.py @@ -21,8 +21,8 @@ import socket import threading from queue import Queue -from yr.common.singleton import Singleton -from yr.functionsdk import logger +from yuanrong.common.singleton import Singleton +from yuanrong.functionsdk import logger class Log: diff --git a/api/python/yr/functionsdk/utils.py b/api/python/yuanrong/functionsdk/utils.py similarity index 100% rename from api/python/yr/functionsdk/utils.py rename to api/python/yuanrong/functionsdk/utils.py diff --git a/api/python/yr/generator.py b/api/python/yuanrong/generator.py similarity index 96% rename from api/python/yr/generator.py rename to api/python/yuanrong/generator.py index 0ca6a32..1af7553 100644 --- a/api/python/yr/generator.py +++ b/api/python/yuanrong/generator.py @@ -18,10 +18,10 @@ import asyncio import logging from typing import Optional -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.fnruntime import GeneratorEndError -from yr.exception import GeneratorFinished +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.fnruntime import GeneratorEndError +from yuanrong.exception import GeneratorFinished _logger = logging.getLogger(__name__) diff --git a/api/python/yr/group.py b/api/python/yuanrong/group.py similarity index 94% rename from api/python/yr/group.py rename to api/python/yuanrong/group.py index 921e00b..9350d1b 100644 --- a/api/python/yr/group.py +++ b/api/python/yuanrong/group.py @@ -15,8 +15,8 @@ # limitations under the License. from dataclasses import dataclass -from yr.config import GroupOptions -from yr import log, runtime_holder +from yuanrong.config import GroupOptions +from yuanrong import log, runtime_holder @dataclass diff --git a/api/python/yr/includes/__init__.pxd b/api/python/yuanrong/includes/__init__.pxd similarity index 100% rename from api/python/yr/includes/__init__.pxd rename to api/python/yuanrong/includes/__init__.pxd diff --git a/api/python/yr/includes/affinity.pxd b/api/python/yuanrong/includes/affinity.pxd similarity index 100% rename from api/python/yr/includes/affinity.pxd rename to api/python/yuanrong/includes/affinity.pxd diff --git a/api/python/yr/includes/affinity.pxi b/api/python/yuanrong/includes/affinity.pxi similarity index 100% rename from api/python/yr/includes/affinity.pxi rename to api/python/yuanrong/includes/affinity.pxi diff --git a/api/python/yr/includes/buffer.pxi b/api/python/yuanrong/includes/buffer.pxi similarity index 100% rename from api/python/yr/includes/buffer.pxi rename to api/python/yuanrong/includes/buffer.pxi diff --git a/api/python/yr/includes/libruntime.pxd b/api/python/yuanrong/includes/libruntime.pxd similarity index 99% rename from api/python/yr/includes/libruntime.pxd rename to api/python/yuanrong/includes/libruntime.pxd index 6a87ffd..7273e13 100644 --- a/api/python/yr/includes/libruntime.pxd +++ b/api/python/yuanrong/includes/libruntime.pxd @@ -24,7 +24,7 @@ from libcpp.memory cimport shared_ptr from libcpp.optional cimport optional from libcpp.unordered_set cimport unordered_set from libcpp.unordered_map cimport unordered_map -from yr.includes.affinity cimport CAffinity +from yuanrong.includes.affinity cimport CAffinity ctypedef void (*CWaitAsyncCallback) (const string & object_id, const CErrorInfo & error, void *userData) ctypedef void (*CGetAsyncCallback) (shared_ptr[CDataObject] data, const CErrorInfo & error, void *userData) diff --git a/api/python/yr/includes/libruntime.pxi b/api/python/yuanrong/includes/libruntime.pxi similarity index 100% rename from api/python/yr/includes/libruntime.pxi rename to api/python/yuanrong/includes/libruntime.pxi diff --git a/api/python/yr/includes/serialization.pxi b/api/python/yuanrong/includes/serialization.pxi similarity index 100% rename from api/python/yr/includes/serialization.pxi rename to api/python/yuanrong/includes/serialization.pxi diff --git a/api/python/yr/local_mode/__init__.py b/api/python/yuanrong/local_mode/__init__.py similarity index 100% rename from api/python/yr/local_mode/__init__.py rename to api/python/yuanrong/local_mode/__init__.py diff --git a/api/python/yr/local_mode/dependency_manager.py b/api/python/yuanrong/local_mode/dependency_manager.py similarity index 94% rename from api/python/yr/local_mode/dependency_manager.py rename to api/python/yuanrong/local_mode/dependency_manager.py index 39bdaf5..bfa83bc 100644 --- a/api/python/yr/local_mode/dependency_manager.py +++ b/api/python/yuanrong/local_mode/dependency_manager.py @@ -23,9 +23,9 @@ import logging from dataclasses import dataclass from typing import Union, List, Callable, Optional -from yr.local_mode.task_spec import TaskSpec -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/instance.py b/api/python/yuanrong/local_mode/instance.py similarity index 100% rename from api/python/yr/local_mode/instance.py rename to api/python/yuanrong/local_mode/instance.py diff --git a/api/python/yr/local_mode/instance_manager.py b/api/python/yuanrong/local_mode/instance_manager.py similarity index 94% rename from api/python/yr/local_mode/instance_manager.py rename to api/python/yuanrong/local_mode/instance_manager.py index ba2c0f1..8ad6208 100644 --- a/api/python/yr/local_mode/instance_manager.py +++ b/api/python/yuanrong/local_mode/instance_manager.py @@ -23,16 +23,16 @@ from collections import OrderedDict, defaultdict from concurrent.futures import Future from typing import Optional, List, Tuple -from yr.common.utils import generate_task_id, generate_random_id +from yuanrong.common.utils import generate_task_id, generate_random_id -from yr.exception import YRInvokeError +from yuanrong.exception import YRInvokeError -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.scheduler import Scheduler -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.timer import Timer +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.scheduler import Scheduler +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.timer import Timer _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/local_client.py b/api/python/yuanrong/local_mode/local_client.py similarity index 92% rename from api/python/yr/local_mode/local_client.py rename to api/python/yuanrong/local_mode/local_client.py index 958fa0d..a7e32a6 100644 --- a/api/python/yr/local_mode/local_client.py +++ b/api/python/yuanrong/local_mode/local_client.py @@ -18,10 +18,10 @@ import logging import threading -from yr.common.utils import generate_random_id -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.worker import Worker +from yuanrong.common.utils import generate_random_id +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.worker import Worker _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/local_mode_runtime.py b/api/python/yuanrong/local_mode/local_mode_runtime.py similarity index 95% rename from api/python/yr/local_mode/local_mode_runtime.py rename to api/python/yuanrong/local_mode/local_mode_runtime.py index 962e042..b4af10e 100644 --- a/api/python/yr/local_mode/local_mode_runtime.py +++ b/api/python/yuanrong/local_mode/local_mode_runtime.py @@ -21,23 +21,23 @@ from abc import ABC from concurrent import futures from concurrent.futures import Future from typing import Union, Dict, List, Any, Tuple, Callable -from yr.accelerate.shm_broadcast import Handle -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.exception import YRInvokeError -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.common.utils import ( +from yuanrong.accelerate.shm_broadcast import Handle +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.exception import YRInvokeError +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.common.utils import ( generate_random_id, generate_task_id, GaugeData, UInt64CounterData, DoubleCounterData ) -from yr.fnruntime import Producer, Consumer -from yr.local_mode.local_client import LocalClient -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_manager import TaskManager -from yr.libruntime_pb2 import FunctionMeta, InvokeType -from yr.local_mode.task_spec import TaskSpec +from yuanrong.fnruntime import Producer, Consumer +from yuanrong.local_mode.local_client import LocalClient +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_manager import TaskManager +from yuanrong.libruntime_pb2 import FunctionMeta, InvokeType +from yuanrong.local_mode.task_spec import TaskSpec -from yr.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams -from yr.fnruntime import SharedBuffer +from yuanrong.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.fnruntime import SharedBuffer _logger = logging.getLogger(__name__) @@ -453,10 +453,10 @@ class LocalModeRuntime(Runtime, ABC): RuntimeError: The name of ResourceGroup is invalid. Examples: - >>> yr.remove_resource_group("rgname") + >>> yuanrong.remove_resource_group("rgname") >>> - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") - >>> yr.remove_resource_group(rg) + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> yuanrong.remove_resource_group(rg) """ raise RuntimeError("not support in local mode") diff --git a/api/python/yr/local_mode/local_object_store.py b/api/python/yuanrong/local_mode/local_object_store.py similarity index 99% rename from api/python/yr/local_mode/local_object_store.py rename to api/python/yuanrong/local_mode/local_object_store.py index 3d56aed..7343d34 100644 --- a/api/python/yr/local_mode/local_object_store.py +++ b/api/python/yuanrong/local_mode/local_object_store.py @@ -19,7 +19,7 @@ import logging import threading from typing import List -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/scheduler.py b/api/python/yuanrong/local_mode/scheduler.py similarity index 95% rename from api/python/yr/local_mode/scheduler.py rename to api/python/yuanrong/local_mode/scheduler.py index 3321221..5544e57 100644 --- a/api/python/yr/local_mode/scheduler.py +++ b/api/python/yuanrong/local_mode/scheduler.py @@ -19,8 +19,8 @@ from abc import abstractmethod, ABC from typing import Optional, Iterable, List -from yr.local_mode.instance import Instance -from yr.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.instance import Instance +from yuanrong.local_mode.task_spec import TaskSpec class Scorer(ABC): diff --git a/api/python/yr/local_mode/task_manager.py b/api/python/yuanrong/local_mode/task_manager.py similarity index 93% rename from api/python/yr/local_mode/task_manager.py rename to api/python/yuanrong/local_mode/task_manager.py index adfc712..8db2ee4 100644 --- a/api/python/yr/local_mode/task_manager.py +++ b/api/python/yuanrong/local_mode/task_manager.py @@ -24,17 +24,17 @@ from threading import RLock, Lock, BoundedSemaphore, Thread from typing import List from typing import Optional -import yr.apis -from yr.exception import CancelError +import yuanrong.apis +from yuanrong.exception import CancelError -from yr.config import InvokeOptions -from yr.config_manager import ConfigManager -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.instance_manager import InstanceManager -from yr.local_mode.scheduler import NormalScheduler, ConcurrencyScorer -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.timer import Timer +from yuanrong.config import InvokeOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.instance_manager import InstanceManager +from yuanrong.local_mode.scheduler import NormalScheduler, ConcurrencyScorer +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.timer import Timer class TaskState(Enum): @@ -79,8 +79,8 @@ class TaskManager: def submit_task(self, task: TaskSpec): """submit task""" - if not yr.apis.is_initialized(): - _logger.warning("Can not submit task %s before yr.init", task.task_id) + if not yuanrong.apis.is_initialized(): + _logger.warning("Can not submit task %s before yuanrong.init", task.task_id) return if task.invoke_options: invoke_options = task.invoke_options diff --git a/api/python/yr/local_mode/task_spec.py b/api/python/yuanrong/local_mode/task_spec.py similarity index 91% rename from api/python/yr/local_mode/task_spec.py rename to api/python/yuanrong/local_mode/task_spec.py index e7ada53..2f52780 100644 --- a/api/python/yr/local_mode/task_spec.py +++ b/api/python/yuanrong/local_mode/task_spec.py @@ -21,8 +21,8 @@ from concurrent.futures import Future from dataclasses import dataclass, field from typing import List, Any -from yr.config import InvokeOptions -from yr.libruntime_pb2 import FunctionMeta, InvokeType +from yuanrong.config import InvokeOptions +from yuanrong.libruntime_pb2 import FunctionMeta, InvokeType _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/timer.py b/api/python/yuanrong/local_mode/timer.py similarity index 98% rename from api/python/yr/local_mode/timer.py rename to api/python/yuanrong/local_mode/timer.py index 47f23a2..5d4d852 100644 --- a/api/python/yr/local_mode/timer.py +++ b/api/python/yuanrong/local_mode/timer.py @@ -21,7 +21,7 @@ import time from threading import Thread from typing import Callable -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/worker.py b/api/python/yuanrong/local_mode/worker.py similarity index 93% rename from api/python/yr/local_mode/worker.py rename to api/python/yuanrong/local_mode/worker.py index a52e2bf..4c47a0b 100644 --- a/api/python/yr/local_mode/worker.py +++ b/api/python/yuanrong/local_mode/worker.py @@ -22,14 +22,14 @@ import threading import traceback from typing import Iterable -import yr +import yuanrong -from yr import signature -from yr.exception import YRInvokeError, YRError -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_spec import TaskSpec -from yr.object_ref import ObjectRef +from yuanrong import signature +from yuanrong.exception import YRInvokeError, YRError +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.object_ref import ObjectRef _logger = logging.getLogger(__name__) @@ -135,7 +135,7 @@ def _normal_function(task: TaskSpec, *args, **kwargs): def _process_args(args_list): def func(arg): if isinstance(arg, ObjectRef): - return yr.get(arg) + return yuanrong.get(arg) return arg return list(map(func, args_list)) diff --git a/api/python/yr/log.py b/api/python/yuanrong/log.py similarity index 98% rename from api/python/yr/log.py rename to api/python/yuanrong/log.py index 0838cac..928bbe1 100644 --- a/api/python/yr/log.py +++ b/api/python/yuanrong/log.py @@ -25,12 +25,12 @@ import time from logging import Logger import logging.config -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton # MAX_ROW_SIZE max row size of a log _MAX_ROW_SIZE = 1024 * 1024 # python runtime log location -_BASE_LOG_NAME = "yr" +_BASE_LOG_NAME = "yuanrong" _LOG_SUFFIX = "_runtime.log" diff --git a/api/python/yr/main/__init__.py b/api/python/yuanrong/main/__init__.py similarity index 100% rename from api/python/yr/main/__init__.py rename to api/python/yuanrong/main/__init__.py diff --git a/api/python/yr/main/yr_runtime_main.py b/api/python/yuanrong/main/yr_runtime_main.py similarity index 94% rename from api/python/yr/main/yr_runtime_main.py rename to api/python/yuanrong/main/yr_runtime_main.py index df5d743..805b31e 100644 --- a/api/python/yr/main/yr_runtime_main.py +++ b/api/python/yuanrong/main/yr_runtime_main.py @@ -14,17 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""yr runtime main""" +"""yuanrong runtime main""" import argparse import json import os import sys -from yr import init, log -from yr.apis import receive_request_loop -from yr.config import Config -from yr.common.utils import try_install_uvloop +from yuanrong import init, log +from yuanrong.apis import receive_request_loop +from yuanrong.config import Config +from yuanrong.common.utils import try_install_uvloop DEFAULT_LOG_DIR = "/home/snuser/log/" _ENV_KEY_FUNCTION_LIB_PATH = "YR_FUNCTION_LIB_PATH" diff --git a/api/python/yr/metrics.py b/api/python/yuanrong/metrics.py similarity index 88% rename from api/python/yr/metrics.py rename to api/python/yuanrong/metrics.py index b651b57..3c3df2b 100644 --- a/api/python/yr/metrics.py +++ b/api/python/yuanrong/metrics.py @@ -18,10 +18,10 @@ import re from dataclasses import field from typing import Dict -from yr.config_manager import ConfigManager -from yr.runtime import AlarmInfo -from yr.runtime_holder import global_runtime -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.config_manager import ConfigManager +from yuanrong.runtime import AlarmInfo +from yuanrong.runtime_holder import global_runtime +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData _METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$') _METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') @@ -90,15 +90,15 @@ class Gauge(Metrics): ValueError: Labels are missing, or the data does not conform to Prometheus standard requirements. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) - >>> @yr.instance + >>> @yuanrong.instance ... class GaugeActor: ... def __init__(self): ... self.labels = {"key1": "value1"} - ... self.gauge = yr.Gauge( + ... self.gauge = yuanrong.Gauge( ... name="test", ... description="", ... unit="ms", @@ -116,7 +116,7 @@ class Gauge(Metrics): >>> >>> actor = GaugeActor.options(name="gauge_actor").invoke() >>> result = actor.set_value.invoke(75) - >>> print("Driver got:", yr.get(result)) + >>> print("Driver got:", yuanrong.get(result)) """ self._check_label(labels) @@ -137,15 +137,15 @@ class Gauge(Metrics): (such as reporting data types other than float). Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance ... class GaugeActor: ... def __init__(self): ... self.labels = {"key1": "value1"} - ... self.gauge = yr.Gauge( + ... self.gauge = yuanrong.Gauge( ... name="test", ... description="", ... unit="ms", @@ -165,7 +165,7 @@ class Gauge(Metrics): >>> actor = GaugeActor.options(name="gauge_actor").invoke() >>> >>> result = actor.set_value.invoke(75) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ fvalue = float(value) if ConfigManager().is_driver: @@ -210,16 +210,16 @@ class UInt64Counter(Metrics): ValueError: If the label is empty or does not meet the data type requirements. Example: - >>> import yr + >>> import yuanrong >>> - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: ... def __init__(self): ... labels = {"key1": "value1", "key2": "value2"} - ... self.data = yr.UInt64Counter( + ... self.data = yuanrong.UInt64Counter( ... name="test", ... description="", ... unit="ms", @@ -239,7 +239,7 @@ class UInt64Counter(Metrics): ... return msg >>> >>> actor1 = Actor.options(name="actor").invoke() - >>> print(yr.get(actor1.run.invoke())) + >>> print(yuanrong.get(actor1.run.invoke())) """ self._check_label(labels) @@ -259,14 +259,14 @@ class UInt64Counter(Metrics): ValueError: Invoked in the driver. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance ... class MyActor: ... def __init__(self): - ... self.data = yr.UInt64Counter( + ... self.data = yuanrong.UInt64Counter( ... "userFuncTime", ... "user function cost time", ... "ms", @@ -289,7 +289,7 @@ class UInt64Counter(Metrics): ... } >>> actor = MyActor.options(name="actor").invoke() >>> result = actor.add.invoke(5) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ ivalue = int(value) if ConfigManager().is_driver: @@ -358,15 +358,15 @@ class DoubleCounter(Metrics): ValueError: If the labels are empty. Example: - >>> import yr + >>> import yuanrong >>> - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): - >>> self.data = yr.DoubleCounter( + >>> self.data = yuanrong.DoubleCounter( >>> "userFuncTime", >>> "user function cost time", >>> "ms", @@ -386,7 +386,7 @@ class DoubleCounter(Metrics): >>> return msg >>> actor1 = Actor.options(name="actor").invoke() >>> result = actor1.run.invoke() - >>> print("run result:", yr.get(result)) + >>> print("run result:", yuanrong.get(result)) """ self._check_label(labels) if len(labels) == 0: @@ -405,15 +405,15 @@ class DoubleCounter(Metrics): ValueError: Invoked in the driver. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): >>> try: - >>> self.data = yr.DoubleCounter( + >>> self.data = yuanrong.DoubleCounter( >>> "userFuncTime", >>> "user function cost time", >>> "ms", @@ -489,13 +489,13 @@ class Alarm(Metrics): ValueError: If alarm_name is None. Example: - >>> import yr + >>> import yuanrong >>> import time - >>> config = yr.Config(enable_metrics=True) + >>> config = yuanrong.Config(enable_metrics=True) >>> config.log_level="DEBUG":378 - >>> yr.init(config) + >>> yuanrong.init(config) - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): >>> self.state = 0 @@ -504,8 +504,8 @@ class Alarm(Metrics): >>> def add(self, value): >>> self.state += value >>> if self.state > 10: - >>> alarm_info = yr.AlarmInfo(alarm_name="aad") - >>> alarm = yr.Alarm(self.name, description="") + >>> alarm_info = yuanrong.AlarmInfo(alarm_name="aad") + >>> alarm = yuanrong.Alarm(self.name, description="") >>> alarm.set(alarm_info) >>> return self.state >>> @@ -514,9 +514,9 @@ class Alarm(Metrics): >>> >>> actor1 = Actor.options(name="actor1").invoke() >>> - >>> print("actor1 add 5:", yr.get(actor1.add.invoke(5))) - >>> print("actor1 add 7:", yr.get(actor1.add.invoke(7))) - >>> print("actor1 state:", yr.get(actor1.get.invoke())) + >>> print("actor1 add 5:", yuanrong.get(actor1.add.invoke(5))) + >>> print("actor1 add 7:", yuanrong.get(actor1.add.invoke(7))) + >>> print("actor1 state:", yuanrong.get(actor1.get.invoke())) """ if ConfigManager().is_driver: raise ValueError("alarm metrics set not support in driver") diff --git a/api/python/yr/object_ref.py b/api/python/yuanrong/object_ref.py similarity index 92% rename from api/python/yr/object_ref.py rename to api/python/yuanrong/object_ref.py index 83212de..017630e 100644 --- a/api/python/yr/object_ref.py +++ b/api/python/yuanrong/object_ref.py @@ -21,12 +21,12 @@ import json from concurrent.futures import Future from typing import Any, Union -from yr.exception import YRInvokeError, YRError, GeneratorFinished -from yr.err_type import ErrorInfo, ErrorCode +from yuanrong.exception import YRInvokeError, YRError, GeneratorFinished +from yuanrong.err_type import ErrorInfo, ErrorCode -import yr -from yr import log -from yr.common import constants +import yuanrong +from yuanrong import log +from yuanrong.common import constants def _set_future_helper( @@ -66,12 +66,12 @@ class ObjectRef: self._need_decre = need_decre self._exception = exception self._data = None - global_runtime = yr.runtime_holder.global_runtime.get_runtime() + global_runtime = yuanrong.runtime_holder.global_runtime.get_runtime() if need_incre and global_runtime and exception is None: global_runtime.increase_global_reference([self._id]) def __del__(self): - global_runtime = yr.runtime_holder.global_runtime.get_runtime() + global_runtime = yuanrong.runtime_holder.global_runtime.get_runtime() if self._need_decre and global_runtime: global_runtime.decrease_global_reference([self._id]) @@ -197,7 +197,7 @@ class ObjectRef: Args: callback (Callable): User callback. """ - yr.runtime_holder.global_runtime.get_runtime().set_get_callback(self.id, callback) + yuanrong.runtime_holder.global_runtime.get_runtime().set_get_callback(self.id, callback) def get(self, timeout: int = constants.DEFAULT_GET_TIMEOUT) -> Any: """This function is used to retrieve an object. @@ -217,7 +217,7 @@ class ObjectRef: if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: raise ValueError("Parameter 'timeout' should be greater than 0 or equal to -1 (no timeout)") - objects = yr.runtime_holder.global_runtime.get_runtime().get([self.id], timeout, False) + objects = yuanrong.runtime_holder.global_runtime.get_runtime().get([self.id], timeout, False) result_str = objects[0] try: diff --git a/api/python/yr/resource_group.py b/api/python/yuanrong/resource_group.py similarity index 81% rename from api/python/yr/resource_group.py rename to api/python/yuanrong/resource_group.py index 9bb12a7..555f6d5 100644 --- a/api/python/yr/resource_group.py +++ b/api/python/yuanrong/resource_group.py @@ -16,8 +16,8 @@ from dataclasses import dataclass from typing import Dict, List, Optional -from yr.common import constants -from yr.runtime_holder import global_runtime +from yuanrong.common import constants +from yuanrong.runtime_holder import global_runtime @dataclass @@ -26,7 +26,7 @@ class ResourceGroup: The handle returned after creating a ResourceGroup. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") """ def __init__( @@ -49,7 +49,7 @@ class ResourceGroup: All bundles under the current resource group.Data type is List[Dict]. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> bundles = rg.bundle_specs """ return self.bundles @@ -63,9 +63,9 @@ class ResourceGroup: Number of bundles in the current resource group. Data type is int. Examples: - >>> import yr - >>> yr.init() - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> import yuanrong + >>> yuanrong.init() + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> count = rg.bundle_count >>> print(count) """ @@ -80,9 +80,9 @@ class ResourceGroup: Name of the current resource group. Data type is str. Examples: - >>> import yr - >>> yr.init() - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> import yuanrong + >>> yuanrong.init() + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> name = rg.resource_group_name >>> print(name) """ @@ -101,7 +101,7 @@ class ResourceGroup: ValueError: Timeout is less than ``-1``. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> rg.wait(60) """ if timeout_seconds is None: diff --git a/api/python/yr/resource_group_ref.py b/api/python/yuanrong/resource_group_ref.py similarity index 93% rename from api/python/yr/resource_group_ref.py rename to api/python/yuanrong/resource_group_ref.py index 3c777a2..f20ee59 100644 --- a/api/python/yr/resource_group_ref.py +++ b/api/python/yuanrong/resource_group_ref.py @@ -16,8 +16,8 @@ """ObjectRef""" from typing import Optional -from yr.resource_group import ResourceGroup -from yr.fnruntime import write_to_cbuffer +from yuanrong.resource_group import ResourceGroup +from yuanrong.fnruntime import write_to_cbuffer class RgObjectRef: diff --git a/api/python/yr/runtime.py b/api/python/yuanrong/runtime.py similarity index 98% rename from api/python/yr/runtime.py rename to api/python/yuanrong/runtime.py index 95c11ce..8a257cb 100644 --- a/api/python/yr/runtime.py +++ b/api/python/yuanrong/runtime.py @@ -21,13 +21,13 @@ from dataclasses import dataclass, field from enum import Enum from typing import List, Tuple, Union, Any, Callable, Dict -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.libruntime_pb2 import FunctionMeta -from yr.fnruntime import SharedBuffer -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData -from yr.common import constants -from yr.accelerate.shm_broadcast import Handle +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.libruntime_pb2 import FunctionMeta +from yuanrong.fnruntime import SharedBuffer +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.common import constants +from yuanrong.accelerate.shm_broadcast import Handle class ExistenceOpt(Enum): diff --git a/api/python/yr/runtime_env.py b/api/python/yuanrong/runtime_env.py similarity index 99% rename from api/python/yr/runtime_env.py rename to api/python/yuanrong/runtime_env.py index 7b27d94..ef59b96 100644 --- a/api/python/yr/runtime_env.py +++ b/api/python/yuanrong/runtime_env.py @@ -20,7 +20,7 @@ import uuid from pathlib import Path from typing import Dict -from yr.config import InvokeOptions +from yuanrong.config import InvokeOptions WORKING_DIR_KEY = "WORKING_DIR" CONDA_PREFIX = "CONDA_PREFIX" diff --git a/api/python/yr/runtime_holder.py b/api/python/yuanrong/runtime_holder.py similarity index 86% rename from api/python/yr/runtime_holder.py rename to api/python/yuanrong/runtime_holder.py index edf4386..1f309ed 100644 --- a/api/python/yr/runtime_holder.py +++ b/api/python/yuanrong/runtime_holder.py @@ -18,10 +18,10 @@ runtime holder """ -from yr.config_manager import ConfigManager -from yr.cluster_mode_runtime import ClusterModeRuntime -from yr.local_mode.local_mode_runtime import LocalModeRuntime -from yr.runtime import Runtime +from yuanrong.config_manager import ConfigManager +from yuanrong.cluster_mode_runtime import ClusterModeRuntime +from yuanrong.local_mode.local_mode_runtime import LocalModeRuntime +from yuanrong.runtime import Runtime class RuntimeHolder: @@ -56,7 +56,7 @@ def save_real_instance_id(instance_id, need_order): def init(runtime=global_runtime) -> None: """ - init yr + init yuanrong :param runtime: RuntimeHolder :return: None """ diff --git a/api/python/yr/serialization/__init__.py b/api/python/yuanrong/serialization/__init__.py similarity index 87% rename from api/python/yr/serialization/__init__.py rename to api/python/yuanrong/serialization/__init__.py index fd9f265..4952680 100644 --- a/api/python/yr/serialization/__init__.py +++ b/api/python/yuanrong/serialization/__init__.py @@ -15,6 +15,6 @@ # limitations under the License. """serialization""" -from yr.serialization.serialization import Serialization, register_pack_hook, register_unpack_hook +from yuanrong.serialization.serialization import Serialization, register_pack_hook, register_unpack_hook __all__ = ["Serialization", "register_pack_hook", "register_unpack_hook"] diff --git a/api/python/yr/serialization/serialization.py b/api/python/yuanrong/serialization/serialization.py similarity index 93% rename from api/python/yr/serialization/serialization.py rename to api/python/yuanrong/serialization/serialization.py index 8d9ba67..ef9f7f9 100644 --- a/api/python/yr/serialization/serialization.py +++ b/api/python/yuanrong/serialization/serialization.py @@ -18,11 +18,11 @@ import threading from typing import Any, List, Union -import yr -from yr.common import constants -from yr.common.singleton import Singleton -from yr.fnruntime import SerializedObject, split_buffer, Buffer -from yr.serialization.serializers import MessagePackSerializer, PySerializer, pop_local_object_refs +import yuanrong +from yuanrong.common import constants +from yuanrong.common.singleton import Singleton +from yuanrong.fnruntime import SerializedObject, split_buffer, Buffer +from yuanrong.serialization.serializers import MessagePackSerializer, PySerializer, pop_local_object_refs @Singleton @@ -109,7 +109,7 @@ class Serialization: object_refs = pop_local_object_refs() if len(object_refs) != 0: object_ref_ids = [ref.id for ref in object_refs] - yr.runtime_holder.global_runtime.get_runtime().increase_global_reference(object_ref_ids) + yuanrong.runtime_holder.global_runtime.get_runtime().increase_global_reference(object_ref_ids) return result[0] if is_buffer else result def register_pack_hook(self, hook): diff --git a/api/python/yr/serialization/serializers.py b/api/python/yuanrong/serialization/serializers.py similarity index 96% rename from api/python/yr/serialization/serializers.py rename to api/python/yuanrong/serialization/serializers.py index 72e3021..33e512b 100644 --- a/api/python/yr/serialization/serializers.py +++ b/api/python/yuanrong/serialization/serializers.py @@ -22,17 +22,17 @@ import pickle import cloudpickle import msgpack -import yr -from yr import log -from yr.common.utils import NoGC, err_to_str -from yr.fnruntime import ( +import yuanrong +from yuanrong import log +from yuanrong.common.utils import NoGC, err_to_str +from yuanrong.fnruntime import ( Pickle5Writer, unpack_pickle5_buffers, Pickle5SerializedObject, RawSerializedObject, SerializedInterface ) -from yr.object_ref import ObjectRef +from yuanrong.object_ref import ObjectRef _EXT_TYPE_CODE = 101 _DEFAULT_PROTOCAL = 4 @@ -167,7 +167,7 @@ class PySerializer: obj = PySerializer._deserialize_to_pickle4(serialized_data) nested_refs = pop_local_object_refs() if len(nested_refs) != 0: - yr.runtime_holder.global_runtime.get_runtime().increase_global_reference([ref.id for ref in nested_refs]) + yuanrong.runtime_holder.global_runtime.get_runtime().increase_global_reference([ref.id for ref in nested_refs]) return obj @staticmethod diff --git a/api/python/yr/signature.py b/api/python/yuanrong/signature.py similarity index 100% rename from api/python/yr/signature.py rename to api/python/yuanrong/signature.py diff --git a/api/python/yr/stream.py b/api/python/yuanrong/stream.py similarity index 100% rename from api/python/yr/stream.py rename to api/python/yuanrong/stream.py diff --git a/api/python/yr/tests/BUILD.bazel b/api/python/yuanrong/tests/BUILD.bazel similarity index 100% rename from api/python/yr/tests/BUILD.bazel rename to api/python/yuanrong/tests/BUILD.bazel diff --git a/api/python/yr/tests/test_InvokeOptions.py b/api/python/yuanrong/tests/test_InvokeOptions.py similarity index 97% rename from api/python/yr/tests/test_InvokeOptions.py rename to api/python/yuanrong/tests/test_InvokeOptions.py index fc96612..b91860b 100644 --- a/api/python/yr/tests/test_InvokeOptions.py +++ b/api/python/yuanrong/tests/test_InvokeOptions.py @@ -15,16 +15,16 @@ # limitations under the License. import unittest -import yr +import yuanrong class TestInvokeOptions(unittest.TestCase): def setUp(self): - @yr.invoke + @yuanrong.invoke def add(x): return x + 1 self.add = add - self.opts = yr.InvokeOptions() + self.opts = yuanrong.InvokeOptions() def test_option_function_name(self): self.opts.name = 999 diff --git a/api/python/yr/tests/test_apis.py b/api/python/yuanrong/tests/test_apis.py similarity index 70% rename from api/python/yr/tests/test_apis.py rename to api/python/yuanrong/tests/test_apis.py index 6b0a23c..293ec23 100644 --- a/api/python/yr/tests/test_apis.py +++ b/api/python/yuanrong/tests/test_apis.py @@ -20,27 +20,27 @@ from concurrent.futures import Future import cloudpickle import pytest -import yr -from yr import exception -from yr import fcc -from yr.config_manager import ConfigManager -from yr.config import FunctionGroupOptions -from yr.decorator import function_proxy, instance_proxy -from yr.runtime import AlarmInfo -from yr.object_ref import ObjectRef -from yr.config import InvokeOptions - - -@yr.invoke(return_nums=0) +import yuanrong +from yuanrong import exception +from yuanrong import fcc +from yuanrong.config_manager import ConfigManager +from yuanrong.config import FunctionGroupOptions +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.runtime import AlarmInfo +from yuanrong.object_ref import ObjectRef +from yuanrong.config import InvokeOptions + + +@yuanrong.invoke(return_nums=0) def get(): """get""" return 1 -@yr.instance +@yuanrong.instance class Counter: """Counter""" - @yr.method(return_nums=0) + @yuanrong.method(return_nums=0) def get(self): """get""" return 1 @@ -51,15 +51,15 @@ class TestApi(unittest.TestCase): pass def test_yr_init_failed_when_input_invalid_address(self): - conf = yr.Config() - conf.function_id = "sn:cn:yrk:12345678901234561234567890123456:function:0-yr-test-config-init:$latest" + conf = yuanrong.Config() + conf.function_id = "sn:cn:yrk:12345678901234561234567890123456:function:0-yuanrong-test-config-init:$latest" conf.server_address = "127.0.0.1:11111" conf.in_cluster = False with self.assertRaises(ValueError): - yr.init(conf) + yuanrong.init(conf) - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_wait_when_input_list_return_in_order(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.wait.return_value = (["3", "2", "1"], []) @@ -67,12 +67,12 @@ class TestApi(unittest.TestCase): mock_runtime.decrease_global_reference.return_value = None get_runtime.return_value = mock_runtime is_initialized.return_value = True - refs = [yr.object_ref.ObjectRef("1"), yr.object_ref.ObjectRef("2"), yr.object_ref.ObjectRef("3")] - ready_refs, _ = yr.wait(refs) + refs = [yuanrong.object_ref.ObjectRef("1"), yuanrong.object_ref.ObjectRef("2"), yuanrong.object_ref.ObjectRef("3")] + ready_refs, _ = yuanrong.wait(refs) assert ready_refs == refs - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_invoke_when_return_nums_is_0(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.invoke_by_name.return_value = ["1"] @@ -90,130 +90,130 @@ class TestApi(unittest.TestCase): assert c.get.invoke() is None def test_yr_init_failed_when_input_invaild_function_id(self): - conf = yr.Config() + conf = yuanrong.Config() conf.function_id = "111" conf.in_cluster = False with pytest.raises(ValueError): - yr.init(conf) + yuanrong.init(conf) def test_affinity(self): """ Test the init method of Affinity class. """ - affinity_kind = yr.AffinityKind.INSTANCE - affinity_type = yr.AffinityType.PREFERRED + affinity_kind = yuanrong.AffinityKind.INSTANCE + affinity_type = yuanrong.AffinityType.PREFERRED label_operators = [ - yr.LabelOperator(yr.OperatorType.LABEL_IN, "key", ["value1", "value2"]) + yuanrong.LabelOperator(yuanrong.OperatorType.LABEL_IN, "key", ["value1", "value2"]) ] - affinity = yr.Affinity(affinity_kind, affinity_type, label_operators) + affinity = yuanrong.Affinity(affinity_kind, affinity_type, label_operators) assert affinity_kind == affinity.affinity_kind assert affinity_type == affinity.affinity_type assert label_operators == affinity.label_operators - affinity_scope = yr.AffinityScope.NODE - affinity2 = yr.Affinity(affinity_kind, affinity_type, label_operators, affinity_scope) + affinity_scope = yuanrong.AffinityScope.NODE + affinity2 = yuanrong.Affinity(affinity_kind, affinity_type, label_operators, affinity_scope) assert affinity_scope == affinity2.affinity_scope - @patch("yr.apis.is_initialized") + @patch("yuanrong.apis.is_initialized") def test_cancel_with_invalid_value(self, is_initialized): is_initialized.return_value = True with pytest.raises(TypeError) as e: - yr.cancel("aaa") + yuanrong.cancel("aaa") print(e) assert e.value.__str__() == "obj_refs type error, actual: [], element expect: " with pytest.raises(TypeError) as e: - yr.cancel(["aaa"]) + yuanrong.cancel(["aaa"]) assert e.value.__str__() == "obj_refs type error, actual: [], element expect: " def test_double_counter(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - d = yr.DoubleCounter(name="test", description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name="test", description='', unit="ms", labels=labels) d.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: d.set(100) assert e.value.__str__() == "double counter metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - d = yr.DoubleCounter(name=name, description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name=name, description='', unit="ms", labels=labels) d.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - d = yr.DoubleCounter(name="test", description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name="test", description='', unit="ms", labels=labels) d.set("abc") assert e.value.__str__() == "could not convert string to float: 'abc'" def test_uint64_counter(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - u = yr.UInt64Counter(name="test", description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name="test", description='', unit="ms", labels=labels) u.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: u.set(100) assert e.value.__str__() == "uint64 counter metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - u = yr.UInt64Counter(name=name, description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name=name, description='', unit="ms", labels=labels) u.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - u = yr.UInt64Counter(name="test", description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name="test", description='', unit="ms", labels=labels) u.set("abc") assert e.value.__str__() == "invalid literal for int() with base 10: 'abc'" def test_gauge(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - g = yr.Gauge(name="test", description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name="test", description='', unit="ms", labels=labels) g.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: g.set(100) assert e.value.__str__() == "gauge metrics report not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - g = yr.Gauge(name=name, description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name=name, description='', unit="ms", labels=labels) g.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - g = yr.Gauge(name="test", description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name="test", description='', unit="ms", labels=labels) g.set("abc") assert e.value.__str__() == "could not convert string to float: 'abc'" def test_alarm(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) alarm_info = AlarmInfo() - a = yr.Alarm(name="test", description='') + a = yuanrong.Alarm(name="test", description='') with pytest.raises(ValueError) as e: a.set(alarm_info) assert e.value.__str__() == "alarm metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - a = yr.Alarm(name=name, description='') + a = yuanrong.Alarm(name=name, description='') assert e.value.__str__() == "invalid metric name: *test" def test_serialize_instance_ok(self): - @yr.instance + @yuanrong.instance class Counter1: pass @@ -222,25 +222,25 @@ class TestApi(unittest.TestCase): assert type(b) == type(Counter1) assert type(b.__user_class__) == type(Counter1.__user_class__) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_finalize(self, get_runtime): mock_runtime = Mock() mock_runtime.finalize.return_value = None mock_runtime.receive_request_loop.return_value = None mock_runtime.exit().return_value = None get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - self.assertTrue(yr.apis.is_initialized()) - yr.finalize() - self.assertFalse(yr.apis.is_initialized()) - yr.apis.set_initialized() - yr.exit() - yr.finalize() - yr.apis.receive_request_loop() - self.assertFalse(yr.apis.is_initialized()) - - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + yuanrong.apis.set_initialized() + self.assertTrue(yuanrong.apis.is_initialized()) + yuanrong.finalize() + self.assertFalse(yuanrong.apis.is_initialized()) + yuanrong.apis.set_initialized() + yuanrong.exit() + yuanrong.finalize() + yuanrong.apis.receive_request_loop() + self.assertFalse(yuanrong.apis.is_initialized()) + + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_get_put_wait(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.get.return_value = [1, 2] @@ -249,55 +249,55 @@ class TestApi(unittest.TestCase): is_initialized.return_value = True v = ObjectRef("test") with self.assertRaises(TypeError): - yr.put(v) + yuanrong.put(v) with self.assertRaises(ValueError): - yr.get(v, -2, True) - self.assertFalse(yr.get([])) + yuanrong.get(v, -2, True) + self.assertFalse(yuanrong.get([])) - res = yr.get([v, v]) + res = yuanrong.get([v, v]) self.assertEqual(len(res), 2, len(res)) with self.assertRaises(ValueError): - yr.wait([v, v], 2) + yuanrong.wait([v, v], 2) with self.assertRaises(ValueError): - yr.wait([v], -1) + yuanrong.wait([v], -1) with self.assertRaises(TypeError): - yr.wait([v], "") + yuanrong.wait([v], "") with self.assertRaises(TypeError): - yr.wait([v], 1, "") + yuanrong.wait([v], 1, "") with self.assertRaises(ValueError): - yr.wait([v], 1, -2) + yuanrong.wait([v], 1, -2) with self.assertRaises(ValueError): - yr.wait([v], 1) + yuanrong.wait([v], 1) def test_instance(self): with self.assertRaises(RuntimeError): - @yr.instance(invoke_options=InvokeOptions()) + @yuanrong.instance(invoke_options=InvokeOptions()) def hello(): return "" hello() with self.assertRaises(ValueError): - @yr.method() + @yuanrong.method() def hi(): return "" hi() with self.assertRaises(TypeError): - @yr.method(return_nums="") + @yuanrong.method(return_nums="") def hi(): return "" hi() - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_stream(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.create_stream_producer.return_value = "producer" @@ -311,25 +311,25 @@ class TestApi(unittest.TestCase): get_runtime.return_value = mock_runtime is_initialized.return_value = True - self.assertEqual(yr.create_stream_producer("", None), "producer") + self.assertEqual(yuanrong.create_stream_producer("", None), "producer") - self.assertEqual(yr.create_stream_consumer("", None), "consummer") - self.assertEqual(yr.query_global_producers_num(""), 10) - self.assertEqual(yr.query_global_consumers_num(""), 10) + self.assertEqual(yuanrong.create_stream_consumer("", None), "consummer") + self.assertEqual(yuanrong.query_global_producers_num(""), 10) + self.assertEqual(yuanrong.query_global_consumers_num(""), 10) with self.assertRaises(RuntimeError): - yr.delete_stream("") + yuanrong.delete_stream("") with self.assertRaises(RuntimeError): - yr.kv_write("key", b"abc") + yuanrong.kv_write("key", b"abc") - self.assertEqual(yr.kv_read(""), "value") + self.assertEqual(yuanrong.kv_read(""), "value") with self.assertRaises(RuntimeError): - yr.kv_del("key") + yuanrong.kv_del("key") - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_state(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.save_state.side_effect = RuntimeError("mock exception") @@ -339,14 +339,14 @@ class TestApi(unittest.TestCase): with self.assertRaises(RuntimeError): ConfigManager().local_mode = True - yr.save_state() + yuanrong.save_state() with self.assertRaises(RuntimeError): ConfigManager().local_mode = False - yr.save_state() + yuanrong.save_state() - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_save_and_load_state(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.save_state.return_value = None @@ -356,35 +356,35 @@ class TestApi(unittest.TestCase): ConfigManager()._ConfigManager__in_cluster = True ConfigManager()._ConfigManager__is_driver = False ConfigManager().local_mode = False - yr.save_state() - self.assertEqual(yr.load_state(), None) + yuanrong.save_state() + self.assertEqual(yuanrong.load_state(), None) - @patch("yr.decorator.instance_proxy.get_instance_by_name") + @patch("yuanrong.decorator.instance_proxy.get_instance_by_name") def test_get_instance(self, get_instance_by_name): get_instance_by_name.side_effect = RuntimeError("mock exception") with self.assertRaises(TypeError): - yr.get_instance(1) + yuanrong.get_instance(1) with self.assertRaises(TypeError): - yr.get_instance("instance1", 1, 1) + yuanrong.get_instance("instance1", 1, 1) with self.assertRaises(TypeError): - yr.get_instance("instance1", "namespace", -2) + yuanrong.get_instance("instance1", "namespace", -2) with self.assertRaises(Exception): - yr.get_instance("instance1", "namespace", 1) + yuanrong.get_instance("instance1", "namespace", 1) def tets_resources(self): with self.assertRaises(RuntimeError): ConfigManager().local_mode = True - yr.resources() + yuanrong.resources() - @patch("yr.decorator.instance_proxy.make_cpp_instance_creator") + @patch("yuanrong.decorator.instance_proxy.make_cpp_instance_creator") def test_class_cross_instance(self, make_cpp_instance_creator): make_cpp_instance_creator.return_value = "" - urn = "sn:cn:yrk:12345678901234561234567890123456:function:0-yr-test-config-init:$latest" - cpp_class = yr.apis.cpp_instance_class( + urn = "sn:cn:yrk:12345678901234561234567890123456:function:0-yuanrong-test-config-init:$latest" + cpp_class = yuanrong.apis.cpp_instance_class( "class", "factory", urn) with self.assertRaises(Exception): @@ -397,21 +397,21 @@ class TestApi(unittest.TestCase): self.assertEqual(cpp_class.get_factory_name(), "factory") self.assertTrue("test" in cpp_class.get_function_key()) - cp = yr.apis.cpp_function("class", urn) + cp = yuanrong.apis.cpp_function("class", urn) self.assertEqual(cp.cross_language_info.function_name, "class", cp.cross_language_info) with self.assertRaises(AttributeError): - yr.apis.go_function("class", urn) + yuanrong.apis.go_function("class", urn) - jp = yr.apis.java_function("class", "factory", urn) + jp = yuanrong.apis.java_function("class", "factory", urn) self.assertEqual(jp.cross_language_info.function_name, "factory", jp.cross_language_info) - cp = yr.apis.cpp_instance_class_new( + cp = yuanrong.apis.cpp_instance_class_new( "class", "factory", urn) self.assertTrue(cp) - @patch.object(yr.decorator.instance_proxy.InstanceCreator, "options") - @patch.object(yr.decorator.function_proxy.FunctionProxy, "options") + @patch.object(yuanrong.decorator.instance_proxy.InstanceCreator, "options") + @patch.object(yuanrong.decorator.function_proxy.FunctionProxy, "options") def test_create_function_group(self, mock_function_proxy_options, mock_instance_proxy_options): opt = FunctionGroupOptions() with self.assertRaises(ValueError): @@ -462,8 +462,8 @@ class TestApi(unittest.TestCase): res = fcc.create_function_group(fp, (1, 2), 10, opt) self.assertEqual(res, "function", res) - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_resource_group(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.create_resource_group.return_value = None @@ -471,20 +471,20 @@ class TestApi(unittest.TestCase): mock_runtime.wait_resource_group.return_value = None get_runtime.return_value = mock_runtime is_initialized.return_value = True - rg = yr.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], "rgname") + rg = yuanrong.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], "rgname") self.assertTrue(rg) rg.wait() bundles = rg.bundle_specs assert bundles == [{"NPU": 1}, {"CPU": 2000, "Memory": 2000}] count = rg.bundle_count assert count == 2 - yr.remove_resource_group("rgname") + yuanrong.remove_resource_group("rgname") with self.assertRaises(TypeError): - rg = yr.create_resource_group(None, "rgname") + rg = yuanrong.create_resource_group(None, "rgname") with self.assertRaises(ValueError): - rg = yr.create_resource_group([], "rgname") + rg = yuanrong.create_resource_group([], "rgname") with self.assertRaises(TypeError): - rg = yr.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], []) + rg = yuanrong.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], []) class TestException(unittest.TestCase): diff --git a/api/python/yr/tests/test_apis_get.py b/api/python/yuanrong/tests/test_apis_get.py similarity index 81% rename from api/python/yr/tests/test_apis_get.py rename to api/python/yuanrong/tests/test_apis_get.py index 03a61b7..bcabb74 100644 --- a/api/python/yr/tests/test_apis_get.py +++ b/api/python/yuanrong/tests/test_apis_get.py @@ -15,21 +15,21 @@ # limitations under the License. import unittest -import yr +import yuanrong from unittest.mock import patch, Mock -from yr.object_ref import ObjectRef +from yuanrong.object_ref import ObjectRef class TestGet(unittest.TestCase): - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_get_invalid_timeout(self, mock_get_runtime): - obj_ref = yr.object_ref.ObjectRef(123) + obj_ref = yuanrong.object_ref.ObjectRef(123) time = -10 mock_get_runtime =Mock() mock_get_runtime.get.return_value="Parameter 'timeout' should be greater than 0 or equal to -1 (no timeout)" mock_get_runtime.return_value=mock_get_runtime - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.apis.get(obj_ref,time) + yuanrong.apis.get(obj_ref,time) if __name__ == '__main__': diff --git a/api/python/yr/tests/test_apis_put.py b/api/python/yuanrong/tests/test_apis_put.py similarity index 68% rename from api/python/yr/tests/test_apis_put.py rename to api/python/yuanrong/tests/test_apis_put.py index 6be6cca..b17d97f 100644 --- a/api/python/yr/tests/test_apis_put.py +++ b/api/python/yuanrong/tests/test_apis_put.py @@ -15,89 +15,89 @@ # limitations under the License. import unittest -import yr -from yr.object_ref import ObjectRef +import yuanrong +from yuanrong.object_ref import ObjectRef from unittest.mock import patch, Mock class TestPut(unittest.TestCase): - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_memoryview(self, mock_get_runtime): obj_refs = memoryview(bytearray(10 * 1024 * 1024)) mock_runtime = Mock() mock_runtime.put.return_value = 1 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_bytes(self, mock_get_runtime): obj_refs = bytes(10 * 1024 * 1024) mock_runtime = Mock() mock_runtime.put.return_value = 10 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_bytearray(self, mock_get_runtime): obj_refs = bytearray(10 * 1024 * 1024) mock_runtime = Mock() mock_runtime.put.return_value = 1 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_object_ref(self, mock_rt): mock_rt.return_value.put.side_effect = TypeError obj = ObjectRef(1) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(TypeError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_fail(self, mock_rt): mock_rt.return_value.put.side_effect = RuntimeError("mock error") with self.assertRaises(RuntimeError): - yr.put(1) + yuanrong.put(1) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_null_ptr(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError("value is None or has zero length") obj = None - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_bytes(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError obj = bytes(0) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_bytearray(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError obj = bytearray(0) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_memoryview(self, mock_rt): mock_rt.return_value.put.side_effect = ValueError o = bytes(0) obj = memoryview(o) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) diff --git a/api/python/yr/tests/test_cluster_mode_runtime.py b/api/python/yuanrong/tests/test_cluster_mode_runtime.py similarity index 94% rename from api/python/yr/tests/test_cluster_mode_runtime.py rename to api/python/yuanrong/tests/test_cluster_mode_runtime.py index ce6c63d..ca764a3 100644 --- a/api/python/yr/tests/test_cluster_mode_runtime.py +++ b/api/python/yuanrong/tests/test_cluster_mode_runtime.py @@ -16,13 +16,13 @@ import unittest from unittest.mock import Mock -import yr -from yr.config_manager import ConfigManager -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.serialization import Serialization -from yr.libruntime_pb2 import ApiType, FunctionMeta -from yr.object_ref import ObjectRef -from yr.runtime import CreateParam +import yuanrong +from yuanrong.config_manager import ConfigManager +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.serialization import Serialization +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime import CreateParam class TestClusterModeRuntime(unittest.TestCase): @@ -30,7 +30,7 @@ class TestClusterModeRuntime(unittest.TestCase): def setUp(self): ConfigManager().rt_server_address = "127.0.0.1:1122" - self.runtime = yr.cluster_mode_runtime.ClusterModeRuntime() + self.runtime = yuanrong.cluster_mode_runtime.ClusterModeRuntime() self.runtime.set_initialized() def mock_get_async(obj_id, callback_wrapper): @@ -128,20 +128,20 @@ class TestClusterModeRuntime(unittest.TestCase): def test_stream(self): with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.max_stream_size = -1 self.runtime.create_stream_producer("stream", cfg) with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.retain_for_num_consumers = -1 self.runtime.create_stream_producer("stream", cfg) with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.reserve_size = -1 self.runtime.create_stream_producer("stream", cfg) - self.assertEqual(self.runtime.create_stream_producer("", yr.ProducerConfig()), "producer") - self.assertEqual(self.runtime.create_stream_consumer("", yr.ProducerConfig()), "consumer") + self.assertEqual(self.runtime.create_stream_producer("", yuanrong.ProducerConfig()), "producer") + self.assertEqual(self.runtime.create_stream_consumer("", yuanrong.ProducerConfig()), "consumer") self.assertEqual(self.runtime.query_global_producers_num(""), 10) self.assertEqual(self.runtime.query_global_consumers_num(""), 10) diff --git a/api/python/yr/tests/test_code_manager.py b/api/python/yuanrong/tests/test_code_manager.py similarity index 93% rename from api/python/yr/tests/test_code_manager.py rename to api/python/yuanrong/tests/test_code_manager.py index 82b8e03..c7cef40 100644 --- a/api/python/yr/tests/test_code_manager.py +++ b/api/python/yuanrong/tests/test_code_manager.py @@ -19,9 +19,9 @@ import sys from unittest import mock, TestCase, main -from yr.code_manager import CodeManager -from yr.err_type import ErrorCode -from yr.libruntime_pb2 import FunctionMeta +from yuanrong.code_manager import CodeManager +from yuanrong.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta logger = logging.getLogger(__name__) @@ -41,7 +41,7 @@ class TestCodeManager(TestCase): self.cm.load_functions([path]) mock_sys_path.insert.assert_called_once_with(0, path) - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_functions_when_input_invalid_faas_entry(self, mock_logger): mock_logger.return_value = logger self.cm.custom_handler = "/tmp" @@ -49,14 +49,14 @@ class TestCodeManager(TestCase): assert err.error_code == ErrorCode.ERR_USER_CODE_LOAD @mock.patch.object(CodeManager(), 'load_code_from_local') - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_functions_when_user_code_syntax_err(self, mock_logger, mock_load_code_from_local): mock_logger.return_value = logger mock_load_code_from_local.side_effect = SyntaxError("a syntax error in user code") err = CodeManager().load_functions(["test.init", "test.handler"]) assert err.error_code == ErrorCode.ERR_USER_CODE_LOAD - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_entry_load(self, mock_logger): mock_logger.return_value = logger self.assertFalse(self.cm.get_code_path("none")) @@ -102,7 +102,7 @@ class TestCodeManager(TestCase): @mock.patch("os.path.exists") @mock.patch("importlib.util.spec_from_file_location") @mock.patch("importlib.util.module_from_spec") - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_module(self, mock_logger, mock_module_from_spec, mock_spec_from_file_location, mock_exists): mock_logger.return_value = logger mock_exists.return_value = True diff --git a/api/python/yr/tests/test_common.py b/api/python/yuanrong/tests/test_common.py similarity index 99% rename from api/python/yr/tests/test_common.py rename to api/python/yuanrong/tests/test_common.py index 938b181..a143fb3 100644 --- a/api/python/yr/tests/test_common.py +++ b/api/python/yuanrong/tests/test_common.py @@ -18,7 +18,7 @@ import logging import json from unittest import TestCase, main -from yr.common import utils +from yuanrong.common import utils logger = logging.getLogger(__name__) diff --git a/api/python/yr/tests/test_decorator.py b/api/python/yuanrong/tests/test_decorator.py similarity index 92% rename from api/python/yr/tests/test_decorator.py rename to api/python/yuanrong/tests/test_decorator.py index a702fec..408e373 100644 --- a/api/python/yr/tests/test_decorator.py +++ b/api/python/yuanrong/tests/test_decorator.py @@ -18,11 +18,11 @@ import logging from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.decorator import instance_proxy, function_proxy -from yr.object_ref import ObjectRef -from yr.config import InvokeOptions -from yr.common.utils import CrossLanguageInfo -from yr.libruntime_pb2 import LanguageType, FunctionMeta +from yuanrong.decorator import instance_proxy, function_proxy +from yuanrong.object_ref import ObjectRef +from yuanrong.config import InvokeOptions +from yuanrong.common.utils import CrossLanguageInfo +from yuanrong.libruntime_pb2 import LanguageType, FunctionMeta logger = logging.getLogger(__name__) @@ -30,8 +30,8 @@ logger = logging.getLogger(__name__) class TestDecorator(TestCase): - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") def test_instance_proxy(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() @@ -116,8 +116,8 @@ class TestDecorator(TestCase): decorator = instance_proxy.make_decorator() decorator("test") - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") def test_function_proxy(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() diff --git a/api/python/yr/tests/test_executor.py b/api/python/yuanrong/tests/test_executor.py similarity index 82% rename from api/python/yr/tests/test_executor.py rename to api/python/yuanrong/tests/test_executor.py index 3fcfa4c..26cf65f 100644 --- a/api/python/yr/tests/test_executor.py +++ b/api/python/yuanrong/tests/test_executor.py @@ -19,20 +19,20 @@ import os from unittest import TestCase, main from unittest.mock import Mock, patch -import yr -from yr.executor.posix_handler import PosixHandler -from yr.executor.faas_handler import FaasHandler -from yr.executor.function_handler import FunctionHandler -from yr.executor.executor import INIT_HANDLER, Executor -import yr.executor.faas_executor as faas -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +import yuanrong +from yuanrong.executor.posix_handler import PosixHandler +from yuanrong.executor.faas_handler import FaasHandler +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.executor.executor import INIT_HANDLER, Executor +import yuanrong.executor.faas_executor as faas +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType logger = logging.getLogger(__name__) class TestExecutor(TestCase): def setUp(self) -> None: - self.runtime = yr.cluster_mode_runtime.ClusterModeRuntime() + self.runtime = yuanrong.cluster_mode_runtime.ClusterModeRuntime() mock_fnruntime = Mock() mock_fnruntime.get.return_value = [b"data1", b"data2"] mock_fnruntime.config.libruntimeOptions.functionExecuteCallback = Mock() @@ -53,25 +53,25 @@ class TestExecutor(TestCase): isAsync=False) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_load_excutor(self, mock_logger): mock_logger.return_value = logger os.environ[INIT_HANDLER] = "yrlib_handler.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, FunctionHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") os.environ[INIT_HANDLER] = "faas_executor.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, FaasHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") os.environ[INIT_HANDLER] = "posix.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, PosixHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_executor(self, mock_logger): mock_logger.return_value = logger e = Executor(self.function_meta, [], InvokeType.CreateInstanceStateless, 1, None, False) diff --git a/api/python/yr/tests/test_faas_handler.py b/api/python/yuanrong/tests/test_faas_handler.py similarity index 89% rename from api/python/yr/tests/test_faas_handler.py rename to api/python/yuanrong/tests/test_faas_handler.py index aa58e8a..d15630a 100644 --- a/api/python/yr/tests/test_faas_handler.py +++ b/api/python/yuanrong/tests/test_faas_handler.py @@ -18,20 +18,20 @@ import logging import json from unittest import TestCase, main from unittest.mock import Mock, patch -import yr.executor.faas_executor as faas -from yr.code_manager import CodeManager +import yuanrong.executor.faas_executor as faas +from yuanrong.code_manager import CodeManager -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType -from yr.functionsdk.context import load_context_meta -from yr.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +from yuanrong.functionsdk.context import load_context_meta +from yuanrong.err_type import ErrorCode logger = logging.getLogger(__name__) class TestFaasExecutor(TestCase): - @patch("yr.log.get_logger") - @patch("yr.executor.faas_executor.parse_faas_param") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.executor.faas_executor.parse_faas_param") @patch.object(CodeManager(), 'get_code_path') @patch.object(CodeManager(), 'load') def test_parse_faas_param(self, mock_load, mock_get_code_path, parse_faas_param, mock_logger): @@ -74,9 +74,9 @@ class TestFaasExecutor(TestCase): self.assertTrue("faas init request args json decode error" in str(e), str(e)) parse_faas_param.reset_mock() - @patch("yr.log.get_logger") - @patch("yr.executor.faas_executor.parse_faas_param") - @patch("yr.executor.faas_executor.get_trace_id_from_params") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.executor.faas_executor.parse_faas_param") + @patch("yuanrong.executor.faas_executor.get_trace_id_from_params") @patch.object(CodeManager(), 'load') def test_faas_call_handler(self, mock_load, get_trace_id_from_params, mock_parse_faas_param, mock_logger): mock_logger.return_value = logger @@ -117,7 +117,7 @@ class TestFaasExecutor(TestCase): res = faas.faas_call_handler(["arg0", "arg1"]) self.assertTrue("failed to convert the result to a JSON string" in res, res) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load') def test_faas_shutdown_handler(self, mock_load, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_fcc.py b/api/python/yuanrong/tests/test_fcc.py similarity index 87% rename from api/python/yr/tests/test_fcc.py rename to api/python/yuanrong/tests/test_fcc.py index fe5e2ef..90f712b 100644 --- a/api/python/yr/tests/test_fcc.py +++ b/api/python/yuanrong/tests/test_fcc.py @@ -20,15 +20,15 @@ import logging import time import asyncio from dataclasses import asdict -from yr.decorator.instance_proxy import FunctionGroupHandler +from yuanrong.decorator.instance_proxy import FunctionGroupHandler from unittest import TestCase, main from unittest.mock import patch, Mock, AsyncMock -from yr.fnruntime import SharedBuffer -from yr.accelerate.shm_broadcast import Handle -from yr.accelerate.executor import Worker -from yr.executor.instance_manager import InstanceManager -from yr.accelerate.shm_broadcast import STOP_EVENT, MessageQueue -import yr +from yuanrong.fnruntime import SharedBuffer +from yuanrong.accelerate.shm_broadcast import Handle +from yuanrong.accelerate.executor import Worker +from yuanrong.executor.instance_manager import InstanceManager +from yuanrong.accelerate.shm_broadcast import STOP_EVENT, MessageQueue +import yuanrong import threading logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) @@ -63,7 +63,7 @@ class TestFcc(unittest.TestCase): def setUp(self) -> None: pass - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_accelerate(self, get_runtime): data = bytearray(10 * 1024 * 1024) shared_buffer = SharedBuffer() @@ -84,7 +84,7 @@ class TestFcc(unittest.TestCase): self.assertIsNone(handler.terminate()) def test_worker_sync(self): - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger InstanceManager().instance = new_instance mock_queue = Mock() mock_queue.dequeue.return_value = ("obj", "get", (1, 2), {}) @@ -103,7 +103,7 @@ class TestFcc(unittest.TestCase): self.assertIsNone(worker.worker_busy_loop_sync()) def test_worker_async(self): - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger mock_queue = AsyncMock() InstanceManager().instance = new_instance mock_queue.dequeue_async.return_value = ("obj", "get", (1, 2), {}) @@ -121,10 +121,10 @@ class TestFcc(unittest.TestCase): thread.start() self.assertIsNone(asyncio.run(worker.worker_busy_loop_async())) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_message_queue_sync(self, get_runtime): STOP_EVENT.clear() - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger logger.info("==========================") data = bytearray((10 * 1024 * 1024 + 2) * 10) shared_buffer = MockSharedMemory(data) @@ -143,10 +143,10 @@ class TestFcc(unittest.TestCase): r_queue = MessageQueue.create_from_handle(handle) self.assertIsNotNone(r_queue.dequeue()) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_message_queue_async(self, get_runtime): STOP_EVENT.clear() - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger data = bytearray((10 * 1024 * 1024 + 2) * 10) shared_buffer = MockSharedMemory(data) mock_runtime = Mock() diff --git a/api/python/yr/tests/test_function_handler.py b/api/python/yuanrong/tests/test_function_handler.py similarity index 95% rename from api/python/yr/tests/test_function_handler.py rename to api/python/yuanrong/tests/test_function_handler.py index 864a260..ef7fcea 100644 --- a/api/python/yr/tests/test_function_handler.py +++ b/api/python/yuanrong/tests/test_function_handler.py @@ -19,11 +19,11 @@ import logging import inspect from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.executor.function_handler import FunctionHandler -from yr.code_manager import CodeManager -from yr.serialization import Serialization -from yr.err_type import ErrorCode -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.code_manager import CodeManager +from yuanrong.serialization import Serialization +from yuanrong.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType logger = logging.getLogger(__name__) @@ -45,7 +45,7 @@ class TestFunctionExecutor(TestCase): isGenerator=False, isAsync=False) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load_code') def test_execute_function(self, mock_load_code, mock_logger): mock_logger.return_value = logger @@ -128,7 +128,7 @@ class TestFunctionExecutor(TestCase): err = self.handler.shutdown(10) self.assertTrue(err.error_code == ErrorCode.ERR_OK, err.error_code) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load_code') def test_execute_async_function(self, mock_load_code, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_functionsdk.py b/api/python/yuanrong/tests/test_functionsdk.py similarity index 95% rename from api/python/yr/tests/test_functionsdk.py rename to api/python/yuanrong/tests/test_functionsdk.py index 0514894..45540f6 100644 --- a/api/python/yr/tests/test_functionsdk.py +++ b/api/python/yuanrong/tests/test_functionsdk.py @@ -18,11 +18,11 @@ import os import json import logging from logging import handlers -from yr.functionsdk import context -from yr.functionsdk import function -from yr.functionsdk import utils -from yr.functionsdk import logger as sdklogger -from yr.functionsdk import logger_manager +from yuanrong.functionsdk import context +from yuanrong.functionsdk import function +from yuanrong.functionsdk import utils +from yuanrong.functionsdk import logger as sdklogger +from yuanrong.functionsdk import logger_manager from unittest import TestCase, main from unittest.mock import Mock, patch import os @@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) class TestFunctionSdk(TestCase): - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_context(self, mock_logger): mock_logger.return_value = logger @@ -57,8 +57,8 @@ class TestFunctionSdk(TestCase): self.assertEqual(invoke_context.get_trace_id(), "12345") self.assertEqual(invoke_context.getUserData("TEST_ENV_KEY"), "test_env_value") - @patch("yr.log.get_logger") - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_invoke(self, get_runtime, mock_logger): mock_logger.return_value = logger @@ -96,8 +96,8 @@ class TestFunctionSdk(TestCase): with self.assertRaises(TypeError): function.Function(func_name) - @patch("yr.log.get_logger") - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_invoke_alias(self, get_runtime, mock_logger): mock_logger.return_value = logger @@ -135,7 +135,7 @@ class TestFunctionSdk(TestCase): with self.assertRaises(TypeError): function.Function(func_name) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_private_function(self, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_generator.py b/api/python/yuanrong/tests/test_generator.py similarity index 90% rename from api/python/yr/tests/test_generator.py rename to api/python/yuanrong/tests/test_generator.py index ffd7273..36c4bc2 100644 --- a/api/python/yr/tests/test_generator.py +++ b/api/python/yuanrong/tests/test_generator.py @@ -20,10 +20,10 @@ import logging from unittest.mock import Mock, patch from concurrent.futures import Future -import yr -from yr.fnruntime import GeneratorEndError -from yr.generator import ObjectRefGenerator -from yr.object_ref import ObjectRef +import yuanrong +from yuanrong.fnruntime import GeneratorEndError +from yuanrong.generator import ObjectRefGenerator +from yuanrong.object_ref import ObjectRef logger = logging.getLogger(__name__) @@ -78,8 +78,8 @@ class testObjectRef(unittest.TestCase): obj.set_data("data") self.assertEqual(obj.get_future().result(), "data") - @patch('yr.runtime_holder.global_runtime.get_runtime') - @patch("yr.log.get_logger") + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') + @patch("yuanrong.log.get_logger") def test_get(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() @@ -98,7 +98,7 @@ class TestObjectRefGenerator(unittest.TestCase): def setUp(self): pass - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_iter(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.return_value = 'test_object_id' @@ -108,7 +108,7 @@ class TestObjectRefGenerator(unittest.TestCase): ObjectRef(generator_id, need_incre=False)) self.assertEqual(iter(generator), generator) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_next_sync(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.return_value = 'test_object_id' @@ -119,7 +119,7 @@ class TestObjectRefGenerator(unittest.TestCase): self.assertEqual(generator._next_sync().id, 'test_object_id') print("finished test_next_sync") - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_next_sync_with_exception(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.side_effect = GeneratorEndError("failed") diff --git a/api/python/yr/tests/test_instance_manager.py b/api/python/yuanrong/tests/test_instance_manager.py similarity index 95% rename from api/python/yr/tests/test_instance_manager.py rename to api/python/yuanrong/tests/test_instance_manager.py index a8a3a13..ed90f1f 100644 --- a/api/python/yr/tests/test_instance_manager.py +++ b/api/python/yuanrong/tests/test_instance_manager.py @@ -15,7 +15,7 @@ # limitations under the License. import unittest -from yr.executor.instance_manager import InstanceManager, InstancePackage +from yuanrong.executor.instance_manager import InstanceManager, InstancePackage class TestInstanceManager(unittest.TestCase): def setUp(self) -> None: diff --git a/api/python/yr/tests/test_local_mode.py b/api/python/yuanrong/tests/test_local_mode.py similarity index 88% rename from api/python/yr/tests/test_local_mode.py rename to api/python/yuanrong/tests/test_local_mode.py index f18713d..899b34d 100644 --- a/api/python/yr/tests/test_local_mode.py +++ b/api/python/yuanrong/tests/test_local_mode.py @@ -17,15 +17,15 @@ from unittest import TestCase, main import time import concurrent.futures -import yr -from yr.object_ref import ObjectRef -from yr.exception import YRInvokeError -from yr.local_mode.local_mode_runtime import LocalModeRuntime -from yr.local_mode import local_client, instance_manager -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.local_object_store import LocalObjectStore -from yr.runtime import SetParam +import yuanrong +from yuanrong.object_ref import ObjectRef +from yuanrong.exception import YRInvokeError +from yuanrong.local_mode.local_mode_runtime import LocalModeRuntime +from yuanrong.local_mode import local_client, instance_manager +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.runtime import SetParam class Mock(object): @@ -37,15 +37,15 @@ class TestApi(TestCase): pass def test_local_mode_base(self): - @yr.invoke + @yuanrong.invoke def func(x): return x - yr.init(yr.Config(local_mode=True, log_level="DEBUG")) - assert yr.get(func.invoke(1)) == 1 - assert yr.get(func.invoke(func.invoke(1))) == 1 + yuanrong.init(yuanrong.Config(local_mode=True, log_level="DEBUG")) + assert yuanrong.get(func.invoke(1)) == 1 + assert yuanrong.get(func.invoke(func.invoke(1))) == 1 - @yr.instance + @yuanrong.instance class Counter: cnt = 0 @@ -61,28 +61,28 @@ class TestApi(TestCase): return self.cnt c = Counter.invoke() - assert yr.get(c.get.invoke()) == 0 - assert yr.get(c.add.invoke()) == 1 + assert yuanrong.get(c.get.invoke()) == 0 + assert yuanrong.get(c.add.invoke()) == 1 obj_id = c.add.invoke() - ready, _ = yr.wait(obj_id, 1, 2) + ready, _ = yuanrong.wait(obj_id, 1, 2) self.assertTrue(len(ready) == 1, len(ready)) - assert yr.get(ready[0]) == 2 + assert yuanrong.get(ready[0]) == 2 obj_id = c.delay.invoke() - yr.cancel(obj_id) + yuanrong.cancel(obj_id) obj_id = ObjectRef(object_id="noid") with self.assertRaises(RuntimeError): - yr.cancel(obj_id) + yuanrong.cancel(obj_id) obj = func.invoke(1) def cb(): return obj.on_complete(cb) - self.assertEqual(yr.get(obj), 1) + self.assertEqual(yuanrong.get(obj), 1) def test_local_mode_runtime(self): lr = LocalModeRuntime() @@ -281,7 +281,7 @@ class TestApi(TestCase): trace_id="trace1234", ) instance_id, _ = ins_mgr.scale_out(task, res) - self.assertIn("yr-api-obj", instance_id) + self.assertIn("yuanrong-api-obj", instance_id) get_ins = ins_mgr.get_instances(res) self.assertEqual(len(get_ins), 1, len(get_ins)) diff --git a/api/python/yr/tests/test_metrics.py b/api/python/yuanrong/tests/test_metrics.py similarity index 93% rename from api/python/yr/tests/test_metrics.py rename to api/python/yuanrong/tests/test_metrics.py index 9a829e5..4e8e4f0 100644 --- a/api/python/yr/tests/test_metrics.py +++ b/api/python/yuanrong/tests/test_metrics.py @@ -17,13 +17,13 @@ from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.config_manager import ConfigManager -from yr.config import Config -from yr import Gauge, UInt64Counter, DoubleCounter +from yuanrong.config_manager import ConfigManager +from yuanrong.config import Config +from yuanrong import Gauge, UInt64Counter, DoubleCounter class TestMetrics(TestCase): - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_gauge(self, get_runtime): mock_runtime = Mock() mock_runtime.report_gauge.side_effect = RuntimeError("mock exception") @@ -56,7 +56,7 @@ class TestMetrics(TestCase): ConfigManager().init(Config(is_driver=False, ds_address="127.0.0.1:31222")) data.set(1) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_uint64_counter(self, get_runtime): mock_runtime = Mock() mock_runtime.set_uint64_counter.side_effect = RuntimeError("mock exception") @@ -97,7 +97,7 @@ class TestMetrics(TestCase): ConfigManager().init(Config(is_driver=False, ds_address="127.0.0.1:31222")) self.assertEqual(data.get_value(), 10) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_double_counter(self, get_runtime): mock_runtime = Mock() mock_runtime.set_double_counter.side_effect = RuntimeError("mock exception") diff --git a/api/python/yr/tests/test_runtime_env.py b/api/python/yuanrong/tests/test_runtime_env.py similarity index 99% rename from api/python/yr/tests/test_runtime_env.py rename to api/python/yuanrong/tests/test_runtime_env.py index 7636370..7ae7a04 100644 --- a/api/python/yr/tests/test_runtime_env.py +++ b/api/python/yuanrong/tests/test_runtime_env.py @@ -20,7 +20,7 @@ import tempfile import unittest from unittest.mock import patch, Mock -from yr import runtime_env, InvokeOptions +from yuanrong import runtime_env, InvokeOptions class TestPut(unittest.TestCase): diff --git a/api/python/yr/tests/test_serialization.py b/api/python/yuanrong/tests/test_serialization.py similarity index 93% rename from api/python/yr/tests/test_serialization.py rename to api/python/yuanrong/tests/test_serialization.py index 68d66d1..e278ff9 100644 --- a/api/python/yr/tests/test_serialization.py +++ b/api/python/yuanrong/tests/test_serialization.py @@ -17,9 +17,9 @@ import unittest import pickle from unittest.mock import patch, Mock -from yr.common import constants -from yr.serialization import Serialization -from yr.fnruntime import write_to_cbuffer +from yuanrong.common import constants +from yuanrong.serialization import Serialization +from yuanrong.fnruntime import write_to_cbuffer import numpy as np @@ -27,7 +27,7 @@ class TestApi(unittest.TestCase): def setUp(self) -> None: pass - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_serialize_base(self, get_runtime): mock_runtime = Mock() mock_runtime.increase_global_reference.return_value = None -- Gitee From 493777f43c3f5a5af96b2f6599ccd01456262226 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:00:50 +0800 Subject: [PATCH 2/9] update --- api/python/BUILD.bazel | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/api/python/BUILD.bazel b/api/python/BUILD.bazel index a0a56d7..07cf960 100644 --- a/api/python/BUILD.bazel +++ b/api/python/BUILD.bazel @@ -40,10 +40,10 @@ platform( pyx_library( name = "fnruntime", srcs = glob([ - "yr/__init__.py", - "yr/fnruntime.pyx", - "yr/includes/*.pxd", - "yr/includes/*.pxi", + "yuanrong/__init__.py", + "yuanrong/fnruntime.pyx", + "yuanrong/includes/*.pxd", + "yuanrong/includes/*.pxi", ]), cc_kwargs = dict( copts = COPTS, @@ -83,13 +83,13 @@ copy_file( filegroup( name = "python_sources", srcs = glob([ - "yr/**/*.py", + "yuanrong/**/*.py", ]), ) cc_strip( name = "py_strip", - srcs = ["yr/fnruntime.so"], + srcs = ["yuanrong/fnruntime.so"], ) genrule( @@ -118,28 +118,28 @@ genrule( echo $$PYTHON_VERSION > $@ ARCH=$$(uname -m) && if [[ "$$PYTHON_VERSION" =~ "3.6" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-36m-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-36m-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.7" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-37m-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-37m-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.8" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-38-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-38-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.9" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-39-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-39-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.10" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-310-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-310-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.11" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-311-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-311-$$ARCH-linux-gnu.so else - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/ + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/ fi - cp -ar $(location //:grpc_strip) $$PYTHON_CODE_DIR/yr/ - ln -f -s libssl.so.1.1 $$PYTHON_CODE_DIR/yr/libssl.so - ln -f -s libcrypto.so.1.1 $$PYTHON_CODE_DIR/yr/libcrypto.so - ln -f -s liblitebus.so.0.0.1 $$PYTHON_CODE_DIR/yr/liblitebus.so + cp -ar $(location //:grpc_strip) $$PYTHON_CODE_DIR/yuanrong/ + ln -f -s libssl.so.1.1 $$PYTHON_CODE_DIR/yuanrong/libssl.so + ln -f -s libcrypto.so.1.1 $$PYTHON_CODE_DIR/yuanrong/libcrypto.so + ln -f -s liblitebus.so.0.0.1 $$PYTHON_CODE_DIR/yuanrong/liblitebus.so - ln -f -s libspdlog.so.1.12.0 $$PYTHON_CODE_DIR/yr/libspdlog.so.1 - ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yr/libspdlog.so - ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yr/libspdlog.so + ln -f -s libspdlog.so.1.12.0 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so.1 + ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so + ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so cd $$BASE_DIR echo "$$BASE_DIR" >> $@ @@ -152,7 +152,7 @@ genrule( srcs = [ "//src/proto:libruntime_py_proto", ], - outs = ["yr/libruntime_pb2.py"], + outs = ["yuanrong/libruntime_pb2.py"], cmd = """ cat "$(location //src/proto:libruntime_py_proto)" >$@ """, @@ -162,12 +162,12 @@ genrule( py_library( name = "yr_lib", srcs = glob( - ["yr/**/*.py"], - exclude = ["yr/tests/*.py"], + ["yuanrong/**/*.py"], + exclude = ["yuanrong/tests/*.py"], ), data = [ - "yr/fnruntime.so", - "yr/libruntime_pb2.py", + "yuanrong/fnruntime.so", + "yuanrong/libruntime_pb2.py", ], visibility = ["__subpackages__"], ) -- Gitee From ee447ef7c72580f182ddf1add5684293976f134c Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:02:51 +0800 Subject: [PATCH 3/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 54 ++++++++++++++++--- api/cpp/include/yr/api/runtime.h | 9 ---- api/cpp/src/cluster_mode_runtime.cpp | 1 - .../cpplibruntime/cpplibruntime.cpp | 1 - .../zh_cn/Python/yr.runtime.CreateParam.rst | 2 - src/libruntime/gwclient/gw_client.cpp | 1 - src/libruntime/objectstore/object_store.h | 1 - 7 files changed, 47 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 06ce896..13ae276 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,47 @@ -**/build/ -/output/ -*.so -__pycache__/ -*.pyc -thirdparty/ -api/cpp/example/3rd/ +bazel-* +.vscode +.clangd +.cache +.idea +.clwb +.ijwb +external +api/cpp/example/3rd +genhtml +compile_commands.json +pyrightconfig.json + +# cpp +*.pb.* +lib*_proto.* + +# java +target/ +*.jar +*.lst +dependency-reduced-pom.xml + +# python +__pycache__ +api/python/yr.egg-info +api/python/dist/*.whl +api/python/yr/*.so* +api/python/yr/libruntime_pb2.py +test/st/python/**/*.log* +test/st/python/pkg + +# test +test/st/cpp/gtest +test/st/yuanrong/ +test/st/**/output.txt +test/st/functions/pkg +test/st/functions/**/*.so +test/st/functions/**/*.zip +test/st/functions/**/*.xml +functionsystem +datasystem +metrics +#thirdparty +thirdparty +go/pkg/mod/ +cmake-build-debug diff --git a/api/cpp/include/yr/api/runtime.h b/api/cpp/include/yr/api/runtime.h index e2a69ab..f149c1d 100644 --- a/api/cpp/include/yr/api/runtime.h +++ b/api/cpp/include/yr/api/runtime.h @@ -261,15 +261,6 @@ struct GetParams { * @brief Configure attributes for the object, such as whether reliability is needed. */ struct CreateParam { - /** - * @brief write mode - * @details Set the reliability of the data. - * When the server configuration supports a secondary cache to ensure reliability, - * such as the Redis service, this configuration can be used to guarantee data reliability. - * Defaults to YR::WriteMode::NONE_L2_CACHE . - */ - WriteMode writeMode = WriteMode::NONE_L2_CACHE; - /** * @brief consistency type * @details Data consistency configuration. In a distributed scenario, diff --git a/api/cpp/src/cluster_mode_runtime.cpp b/api/cpp/src/cluster_mode_runtime.cpp index 8c55ec3..cc87422 100644 --- a/api/cpp/src/cluster_mode_runtime.cpp +++ b/api/cpp/src/cluster_mode_runtime.cpp @@ -224,7 +224,6 @@ YR::Libruntime::GetParams BuildGetParam(const YR::GetParams ¶ms) YR::Libruntime::CreateParam BuildCreateParam(const YR::CreateParam &createParam) { YR::Libruntime::CreateParam dsCreateParam; - dsCreateParam.writeMode = static_cast(createParam.writeMode); dsCreateParam.consistencyType = static_cast(createParam.consistencyType); dsCreateParam.cacheType = static_cast(createParam.cacheType); return dsCreateParam; diff --git a/api/go/libruntime/cpplibruntime/cpplibruntime.cpp b/api/go/libruntime/cpplibruntime/cpplibruntime.cpp index 9fc9da9..4d140b3 100644 --- a/api/go/libruntime/cpplibruntime/cpplibruntime.cpp +++ b/api/go/libruntime/cpplibruntime/cpplibruntime.cpp @@ -214,7 +214,6 @@ MSetParam CMSetParamToMSetParam(CMSetParam param) CreateParam CCreateParamToCreateParam(CCreateParam param) { CreateParam createParam; - createParam.writeMode = static_cast(param.writeMode); createParam.consistencyType = static_cast(param.consistencyType); createParam.cacheType = static_cast(param.cacheType); return createParam; diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst index f8cf0e8..068ad08 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst @@ -31,6 +31,4 @@ yr.runtime.CreateParam yr.runtime.CreateParam.__init__ yr.runtime.CreateParam.cache_type yr.runtime.CreateParam.consistency_type - yr.runtime.CreateParam.write_mode - diff --git a/src/libruntime/gwclient/gw_client.cpp b/src/libruntime/gwclient/gw_client.cpp index bcde946..c315e76 100644 --- a/src/libruntime/gwclient/gw_client.cpp +++ b/src/libruntime/gwclient/gw_client.cpp @@ -885,7 +885,6 @@ PutRequest GwClient::BuildObjPutRequest(std::shared_ptr data, const std: for (const auto &id : nestedID) { req.add_nestedobjectids(id); } - req.set_writemode(static_cast(createParam.writeMode)); req.set_consistencytype(static_cast(createParam.consistencyType)); req.set_cachetype(static_cast(createParam.cacheType)); return req; diff --git a/src/libruntime/objectstore/object_store.h b/src/libruntime/objectstore/object_store.h index b72e6f8..24a28b8 100644 --- a/src/libruntime/objectstore/object_store.h +++ b/src/libruntime/objectstore/object_store.h @@ -48,7 +48,6 @@ struct RetryInfo { }; struct CreateParam { - WriteMode writeMode = WriteMode::NONE_L2_CACHE; ConsistencyType consistencyType = ConsistencyType::PRAM; CacheType cacheType = CacheType::MEMORY; }; -- Gitee From 2e27a59e83ec630ee06c33bddc8d162948631d84 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:18:05 +0800 Subject: [PATCH 4/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reason:修改yr为yuanrong --- api/cpp/include/yr/api/runtime.h | 9 - api/cpp/src/cluster_mode_runtime.cpp | 1 - .../cpplibruntime/cpplibruntime.cpp | 1 - api/python/BUILD.bazel | 50 +-- api/python/{yr => yuanrong}/__init__.py | 28 +- .../{yr => yuanrong}/accelerate/__init__.py | 0 .../{yr => yuanrong}/accelerate/executor.py | 6 +- .../accelerate/shm_broadcast.py | 8 +- api/python/{yr => yuanrong}/affinity.py | 0 api/python/{yr => yuanrong}/apis.py | 372 +++++++++--------- .../{yr => yuanrong}/cluster_mode_runtime.py | 26 +- api/python/{yr => yuanrong}/code_manager.py | 12 +- .../{yr => yuanrong}/common/__init__.py | 0 .../{yr => yuanrong}/common/constants.py | 0 .../{yr => yuanrong}/common/singleton.py | 0 api/python/{yr => yuanrong}/common/types.py | 0 api/python/{yr => yuanrong}/common/utils.py | 8 +- .../{yr => yuanrong}/compiled_dag_ref.py | 26 +- api/python/{yr => yuanrong}/config.py | 36 +- .../config/python-runtime-log.json | 0 api/python/{yr => yuanrong}/config_manager.py | 10 +- .../{yr => yuanrong}/decorator/__init__.py | 0 .../decorator/function_proxy.py | 52 +-- .../decorator/instance_proxy.py | 42 +- api/python/{yr => yuanrong}/device.py | 4 +- api/python/{yr => yuanrong}/err_type.py | 0 api/python/{yr => yuanrong}/exception.py | 8 +- .../{yr => yuanrong}/executor/__init__.py | 0 .../{yr => yuanrong}/executor/executor.py | 16 +- .../executor/faas_executor.py | 20 +- .../{yr => yuanrong}/executor/faas_handler.py | 10 +- .../executor/function_handler.py | 24 +- .../{yr => yuanrong}/executor/handler_intf.py | 2 +- .../executor/instance_manager.py | 4 +- .../executor/posix_handler.py | 2 +- api/python/{yr => yuanrong}/fcc.py | 58 +-- api/python/{yr => yuanrong}/fnruntime.pyx | 0 .../{yr => yuanrong}/functionsdk/__init__.py | 0 .../{yr => yuanrong}/functionsdk/context.py | 6 +- .../functionsdk/error_code.py | 0 .../{yr => yuanrong}/functionsdk/function.py | 18 +- .../{yr => yuanrong}/functionsdk/logger.py | 2 +- .../functionsdk/logger_manager.py | 4 +- .../{yr => yuanrong}/functionsdk/utils.py | 0 api/python/{yr => yuanrong}/generator.py | 8 +- api/python/{yr => yuanrong}/group.py | 4 +- .../{yr => yuanrong}/includes/__init__.pxd | 0 .../{yr => yuanrong}/includes/affinity.pxd | 0 .../{yr => yuanrong}/includes/affinity.pxi | 0 .../{yr => yuanrong}/includes/buffer.pxi | 0 .../{yr => yuanrong}/includes/libruntime.pxd | 2 +- .../{yr => yuanrong}/includes/libruntime.pxi | 0 .../includes/serialization.pxi | 0 .../{yr => yuanrong}/local_mode/__init__.py | 0 .../local_mode/dependency_manager.py | 6 +- .../{yr => yuanrong}/local_mode/instance.py | 0 .../local_mode/instance_manager.py | 16 +- .../local_mode/local_client.py | 8 +- .../local_mode/local_mode_runtime.py | 34 +- .../local_mode/local_object_store.py | 2 +- .../{yr => yuanrong}/local_mode/scheduler.py | 4 +- .../local_mode/task_manager.py | 24 +- .../{yr => yuanrong}/local_mode/task_spec.py | 4 +- .../{yr => yuanrong}/local_mode/timer.py | 2 +- .../{yr => yuanrong}/local_mode/worker.py | 16 +- api/python/{yr => yuanrong}/log.py | 4 +- api/python/{yr => yuanrong}/main/__init__.py | 0 .../{yr => yuanrong}/main/yr_runtime_main.py | 10 +- api/python/{yr => yuanrong}/metrics.py | 96 ++--- api/python/{yr => yuanrong}/object_ref.py | 18 +- api/python/{yr => yuanrong}/resource_group.py | 22 +- .../{yr => yuanrong}/resource_group_ref.py | 4 +- api/python/{yr => yuanrong}/runtime.py | 14 +- api/python/{yr => yuanrong}/runtime_env.py | 2 +- api/python/{yr => yuanrong}/runtime_holder.py | 10 +- .../serialization/__init__.py | 2 +- .../serialization/serialization.py | 12 +- .../serialization/serializers.py | 12 +- api/python/{yr => yuanrong}/signature.py | 0 api/python/{yr => yuanrong}/stream.py | 0 api/python/{yr => yuanrong}/tests/BUILD.bazel | 0 .../tests/test_InvokeOptions.py | 6 +- .../{yr => yuanrong}/tests/test_apis.py | 240 +++++------ .../{yr => yuanrong}/tests/test_apis_get.py | 12 +- .../{yr => yuanrong}/tests/test_apis_put.py | 56 +-- .../tests/test_cluster_mode_runtime.py | 26 +- .../tests/test_code_manager.py | 14 +- .../{yr => yuanrong}/tests/test_common.py | 2 +- .../{yr => yuanrong}/tests/test_decorator.py | 18 +- .../{yr => yuanrong}/tests/test_executor.py | 26 +- .../tests/test_faas_handler.py | 22 +- api/python/{yr => yuanrong}/tests/test_fcc.py | 28 +- .../tests/test_function_handler.py | 14 +- .../tests/test_functionsdk.py | 22 +- .../{yr => yuanrong}/tests/test_generator.py | 18 +- .../tests/test_instance_manager.py | 2 +- .../{yr => yuanrong}/tests/test_local_mode.py | 44 +-- .../{yr => yuanrong}/tests/test_metrics.py | 12 +- .../tests/test_runtime_env.py | 2 +- .../tests/test_serialization.py | 8 +- docs/deploy/deploy_processes/parameters.md | 2 + docs/images/deploy_in_process_mode_1.png | Bin 97193 -> 30902 bytes .../zh_cn/C++/Stream.rst | 3 +- ... => yr.ProducerConfig.max_stream_size.rst} | 0 .../zh_cn/Python/yr.ResourceGroup.wait.rst | 2 +- .../yr.SubscriptionConfig.extend_config.rst | 6 +- .../zh_cn/Python/yr.SubscriptionConfig.rst | 2 +- ...yr.SubscriptionConfig.subscriptionType.rst | 2 +- .../zh_cn/Python/yr.kv_m_write_tx.rst | 2 +- .../zh_cn/Python/yr.runtime.CreateParam.rst | 2 - .../zh_cn/Python/yr.runtime.SetParam.rst | 3 - .../Python/yr.runtime.SetParam.write_mode.rst | 2 +- .../development_guide/data_stream/index.md | 22 +- .../stateless_function/fault-tolerance.md | 2 +- docs/snippets/install-cmd-with-whl.md | 3 - src/libruntime/gwclient/gw_client.cpp | 2 - src/libruntime/objectstore/object_store.h | 1 - 117 files changed, 911 insertions(+), 918 deletions(-) rename api/python/{yr => yuanrong}/__init__.py (82%) rename api/python/{yr => yuanrong}/accelerate/__init__.py (100%) rename api/python/{yr => yuanrong}/accelerate/executor.py (97%) rename api/python/{yr => yuanrong}/accelerate/shm_broadcast.py (98%) rename api/python/{yr => yuanrong}/affinity.py (100%) rename api/python/{yr => yuanrong}/apis.py (85%) rename api/python/{yr => yuanrong}/cluster_mode_runtime.py (96%) rename api/python/{yr => yuanrong}/code_manager.py (97%) rename api/python/{yr => yuanrong}/common/__init__.py (100%) rename api/python/{yr => yuanrong}/common/constants.py (100%) rename api/python/{yr => yuanrong}/common/singleton.py (100%) rename api/python/{yr => yuanrong}/common/types.py (100%) rename api/python/{yr => yuanrong}/common/utils.py (99%) rename api/python/{yr => yuanrong}/compiled_dag_ref.py (92%) rename api/python/{yr => yuanrong}/config.py (96%) rename api/python/{yr => yuanrong}/config/python-runtime-log.json (100%) rename api/python/{yr => yuanrong}/config_manager.py (97%) rename api/python/{yr => yuanrong}/decorator/__init__.py (100%) rename api/python/{yr => yuanrong}/decorator/function_proxy.py (90%) rename api/python/{yr => yuanrong}/decorator/instance_proxy.py (96%) rename api/python/{yr => yuanrong}/device.py (97%) rename api/python/{yr => yuanrong}/err_type.py (100%) rename api/python/{yr => yuanrong}/exception.py (97%) rename api/python/{yr => yuanrong}/executor/__init__.py (100%) rename api/python/{yr => yuanrong}/executor/executor.py (89%) rename api/python/{yr => yuanrong}/executor/faas_executor.py (94%) rename api/python/{yr => yuanrong}/executor/faas_handler.py (83%) rename api/python/{yr => yuanrong}/executor/function_handler.py (92%) rename api/python/{yr => yuanrong}/executor/handler_intf.py (97%) rename api/python/{yr => yuanrong}/executor/instance_manager.py (97%) rename api/python/{yr => yuanrong}/executor/posix_handler.py (95%) rename api/python/{yr => yuanrong}/fcc.py (80%) rename api/python/{yr => yuanrong}/fnruntime.pyx (100%) rename api/python/{yr => yuanrong}/functionsdk/__init__.py (100%) rename api/python/{yr => yuanrong}/functionsdk/context.py (99%) rename api/python/{yr => yuanrong}/functionsdk/error_code.py (100%) rename api/python/{yr => yuanrong}/functionsdk/function.py (96%) rename api/python/{yr => yuanrong}/functionsdk/logger.py (98%) rename api/python/{yr => yuanrong}/functionsdk/logger_manager.py (98%) rename api/python/{yr => yuanrong}/functionsdk/utils.py (100%) rename api/python/{yr => yuanrong}/generator.py (96%) rename api/python/{yr => yuanrong}/group.py (94%) rename api/python/{yr => yuanrong}/includes/__init__.pxd (100%) rename api/python/{yr => yuanrong}/includes/affinity.pxd (100%) rename api/python/{yr => yuanrong}/includes/affinity.pxi (100%) rename api/python/{yr => yuanrong}/includes/buffer.pxi (100%) rename api/python/{yr => yuanrong}/includes/libruntime.pxd (99%) rename api/python/{yr => yuanrong}/includes/libruntime.pxi (100%) rename api/python/{yr => yuanrong}/includes/serialization.pxi (100%) rename api/python/{yr => yuanrong}/local_mode/__init__.py (100%) rename api/python/{yr => yuanrong}/local_mode/dependency_manager.py (94%) rename api/python/{yr => yuanrong}/local_mode/instance.py (100%) rename api/python/{yr => yuanrong}/local_mode/instance_manager.py (94%) rename api/python/{yr => yuanrong}/local_mode/local_client.py (92%) rename api/python/{yr => yuanrong}/local_mode/local_mode_runtime.py (95%) rename api/python/{yr => yuanrong}/local_mode/local_object_store.py (99%) rename api/python/{yr => yuanrong}/local_mode/scheduler.py (95%) rename api/python/{yr => yuanrong}/local_mode/task_manager.py (93%) rename api/python/{yr => yuanrong}/local_mode/task_spec.py (91%) rename api/python/{yr => yuanrong}/local_mode/timer.py (98%) rename api/python/{yr => yuanrong}/local_mode/worker.py (93%) rename api/python/{yr => yuanrong}/log.py (98%) rename api/python/{yr => yuanrong}/main/__init__.py (100%) rename api/python/{yr => yuanrong}/main/yr_runtime_main.py (94%) rename api/python/{yr => yuanrong}/metrics.py (88%) rename api/python/{yr => yuanrong}/object_ref.py (92%) rename api/python/{yr => yuanrong}/resource_group.py (81%) rename api/python/{yr => yuanrong}/resource_group_ref.py (93%) rename api/python/{yr => yuanrong}/runtime.py (98%) rename api/python/{yr => yuanrong}/runtime_env.py (99%) rename api/python/{yr => yuanrong}/runtime_holder.py (86%) rename api/python/{yr => yuanrong}/serialization/__init__.py (87%) rename api/python/{yr => yuanrong}/serialization/serialization.py (93%) rename api/python/{yr => yuanrong}/serialization/serializers.py (96%) rename api/python/{yr => yuanrong}/signature.py (100%) rename api/python/{yr => yuanrong}/stream.py (100%) rename api/python/{yr => yuanrong}/tests/BUILD.bazel (100%) rename api/python/{yr => yuanrong}/tests/test_InvokeOptions.py (97%) rename api/python/{yr => yuanrong}/tests/test_apis.py (70%) rename api/python/{yr => yuanrong}/tests/test_apis_get.py (81%) rename api/python/{yr => yuanrong}/tests/test_apis_put.py (68%) rename api/python/{yr => yuanrong}/tests/test_cluster_mode_runtime.py (94%) rename api/python/{yr => yuanrong}/tests/test_code_manager.py (93%) rename api/python/{yr => yuanrong}/tests/test_common.py (99%) rename api/python/{yr => yuanrong}/tests/test_decorator.py (92%) rename api/python/{yr => yuanrong}/tests/test_executor.py (82%) rename api/python/{yr => yuanrong}/tests/test_faas_handler.py (89%) rename api/python/{yr => yuanrong}/tests/test_fcc.py (87%) rename api/python/{yr => yuanrong}/tests/test_function_handler.py (95%) rename api/python/{yr => yuanrong}/tests/test_functionsdk.py (95%) rename api/python/{yr => yuanrong}/tests/test_generator.py (90%) rename api/python/{yr => yuanrong}/tests/test_instance_manager.py (95%) rename api/python/{yr => yuanrong}/tests/test_local_mode.py (88%) rename api/python/{yr => yuanrong}/tests/test_metrics.py (93%) rename api/python/{yr => yuanrong}/tests/test_runtime_env.py (99%) rename api/python/{yr => yuanrong}/tests/test_serialization.py (93%) rename docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/{yr.ProductConfig.max_stream_size.rst => yr.ProducerConfig.max_stream_size.rst} (100%) delete mode 100644 docs/snippets/install-cmd-with-whl.md diff --git a/api/cpp/include/yr/api/runtime.h b/api/cpp/include/yr/api/runtime.h index e2a69ab..f149c1d 100644 --- a/api/cpp/include/yr/api/runtime.h +++ b/api/cpp/include/yr/api/runtime.h @@ -261,15 +261,6 @@ struct GetParams { * @brief Configure attributes for the object, such as whether reliability is needed. */ struct CreateParam { - /** - * @brief write mode - * @details Set the reliability of the data. - * When the server configuration supports a secondary cache to ensure reliability, - * such as the Redis service, this configuration can be used to guarantee data reliability. - * Defaults to YR::WriteMode::NONE_L2_CACHE . - */ - WriteMode writeMode = WriteMode::NONE_L2_CACHE; - /** * @brief consistency type * @details Data consistency configuration. In a distributed scenario, diff --git a/api/cpp/src/cluster_mode_runtime.cpp b/api/cpp/src/cluster_mode_runtime.cpp index 8c55ec3..cc87422 100644 --- a/api/cpp/src/cluster_mode_runtime.cpp +++ b/api/cpp/src/cluster_mode_runtime.cpp @@ -224,7 +224,6 @@ YR::Libruntime::GetParams BuildGetParam(const YR::GetParams ¶ms) YR::Libruntime::CreateParam BuildCreateParam(const YR::CreateParam &createParam) { YR::Libruntime::CreateParam dsCreateParam; - dsCreateParam.writeMode = static_cast(createParam.writeMode); dsCreateParam.consistencyType = static_cast(createParam.consistencyType); dsCreateParam.cacheType = static_cast(createParam.cacheType); return dsCreateParam; diff --git a/api/go/libruntime/cpplibruntime/cpplibruntime.cpp b/api/go/libruntime/cpplibruntime/cpplibruntime.cpp index 9fc9da9..4d140b3 100644 --- a/api/go/libruntime/cpplibruntime/cpplibruntime.cpp +++ b/api/go/libruntime/cpplibruntime/cpplibruntime.cpp @@ -214,7 +214,6 @@ MSetParam CMSetParamToMSetParam(CMSetParam param) CreateParam CCreateParamToCreateParam(CCreateParam param) { CreateParam createParam; - createParam.writeMode = static_cast(param.writeMode); createParam.consistencyType = static_cast(param.consistencyType); createParam.cacheType = static_cast(param.cacheType); return createParam; diff --git a/api/python/BUILD.bazel b/api/python/BUILD.bazel index a0a56d7..07cf960 100644 --- a/api/python/BUILD.bazel +++ b/api/python/BUILD.bazel @@ -40,10 +40,10 @@ platform( pyx_library( name = "fnruntime", srcs = glob([ - "yr/__init__.py", - "yr/fnruntime.pyx", - "yr/includes/*.pxd", - "yr/includes/*.pxi", + "yuanrong/__init__.py", + "yuanrong/fnruntime.pyx", + "yuanrong/includes/*.pxd", + "yuanrong/includes/*.pxi", ]), cc_kwargs = dict( copts = COPTS, @@ -83,13 +83,13 @@ copy_file( filegroup( name = "python_sources", srcs = glob([ - "yr/**/*.py", + "yuanrong/**/*.py", ]), ) cc_strip( name = "py_strip", - srcs = ["yr/fnruntime.so"], + srcs = ["yuanrong/fnruntime.so"], ) genrule( @@ -118,28 +118,28 @@ genrule( echo $$PYTHON_VERSION > $@ ARCH=$$(uname -m) && if [[ "$$PYTHON_VERSION" =~ "3.6" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-36m-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-36m-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.7" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-37m-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-37m-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.8" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-38-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-38-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.9" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-39-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-39-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.10" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-310-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-310-$$ARCH-linux-gnu.so elif [[ $$PYTHON_VERSION =~ "3.11" ]]; then - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/fnruntime.cpython-311-$$ARCH-linux-gnu.so + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/fnruntime.cpython-311-$$ARCH-linux-gnu.so else - cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yr/ + cp -ar $(location py_strip) $$PYTHON_CODE_DIR/yuanrong/ fi - cp -ar $(location //:grpc_strip) $$PYTHON_CODE_DIR/yr/ - ln -f -s libssl.so.1.1 $$PYTHON_CODE_DIR/yr/libssl.so - ln -f -s libcrypto.so.1.1 $$PYTHON_CODE_DIR/yr/libcrypto.so - ln -f -s liblitebus.so.0.0.1 $$PYTHON_CODE_DIR/yr/liblitebus.so + cp -ar $(location //:grpc_strip) $$PYTHON_CODE_DIR/yuanrong/ + ln -f -s libssl.so.1.1 $$PYTHON_CODE_DIR/yuanrong/libssl.so + ln -f -s libcrypto.so.1.1 $$PYTHON_CODE_DIR/yuanrong/libcrypto.so + ln -f -s liblitebus.so.0.0.1 $$PYTHON_CODE_DIR/yuanrong/liblitebus.so - ln -f -s libspdlog.so.1.12.0 $$PYTHON_CODE_DIR/yr/libspdlog.so.1 - ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yr/libspdlog.so - ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yr/libspdlog.so + ln -f -s libspdlog.so.1.12.0 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so.1 + ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so + ln -f -s libspdlog.so.1 $$PYTHON_CODE_DIR/yuanrong/libspdlog.so cd $$BASE_DIR echo "$$BASE_DIR" >> $@ @@ -152,7 +152,7 @@ genrule( srcs = [ "//src/proto:libruntime_py_proto", ], - outs = ["yr/libruntime_pb2.py"], + outs = ["yuanrong/libruntime_pb2.py"], cmd = """ cat "$(location //src/proto:libruntime_py_proto)" >$@ """, @@ -162,12 +162,12 @@ genrule( py_library( name = "yr_lib", srcs = glob( - ["yr/**/*.py"], - exclude = ["yr/tests/*.py"], + ["yuanrong/**/*.py"], + exclude = ["yuanrong/tests/*.py"], ), data = [ - "yr/fnruntime.so", - "yr/libruntime_pb2.py", + "yuanrong/fnruntime.so", + "yuanrong/libruntime_pb2.py", ], visibility = ["__subpackages__"], ) diff --git a/api/python/yr/__init__.py b/api/python/yuanrong/__init__.py similarity index 82% rename from api/python/yr/__init__.py rename to api/python/yuanrong/__init__.py index ee7c994..d0c0395 100644 --- a/api/python/yr/__init__.py +++ b/api/python/yuanrong/__init__.py @@ -15,7 +15,7 @@ # limitations under the License. """ -yr api +yuanrong api """ import os import ctypes @@ -49,7 +49,7 @@ for so_path in [ # E402: import not at top of file # We must load so before import datasystem, so the lint is not really useful -from yr.apis import ( # noqa: E402 +from yuanrong.apis import ( # noqa: E402 init, finalize, put, get, invoke, instance, wait, cancel, method, exit, @@ -62,28 +62,28 @@ from yr.apis import ( # noqa: E402 list_named_instances ) -from yr.fcc import ( # noqa: E402 +from yuanrong.fcc import ( # noqa: E402 create_function_group, get_function_group_context ) -from yr.resource_group import ResourceGroup # noqa: E402 -from yr.runtime import ( # noqa: E402 +from yuanrong.resource_group import ResourceGroup # noqa: E402 +from yuanrong.runtime import ( # noqa: E402 ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, AlarmSeverity, AlarmInfo, ConsistencyType, GetParams, GetParam ) -from yr.config import ( # noqa: E402 +from yuanrong.config import ( # noqa: E402 Config, InvokeOptions, UserTLSConfig, FunctionGroupOptions, SchedulingAffinityType, FunctionGroupContext, ServerInfo, DeviceInfo, ResourceGroupOptions, GroupOptions, ) -from yr.group import Group -from yr.stream import ProducerConfig, SubscriptionConfig, Element # noqa: E402 -from yr.functionsdk.function import Function # noqa: E402 -from yr.functionsdk.context import Context # noqa: E402 -from yr.affinity import Affinity, AffinityType, AffinityKind, AffinityScope, LabelOperator, OperatorType # noqa: E402 -from yr.metrics import Gauge, Alarm, UInt64Counter, DoubleCounter # noqa: E402 +from yuanrong.group import Group +from yuanrong.stream import ProducerConfig, SubscriptionConfig, Element # noqa: E402 +from yuanrong.functionsdk.function import Function # noqa: E402 +from yuanrong.functionsdk.context import Context # noqa: E402 +from yuanrong.affinity import Affinity, AffinityType, AffinityKind, AffinityScope, LabelOperator, OperatorType # noqa: E402 +from yuanrong.metrics import Gauge, Alarm, UInt64Counter, DoubleCounter # noqa: E402 -from yr.decorator.function_proxy import FunctionProxy # noqa: E402 -from yr.decorator.instance_proxy import ( # noqa: E402 +from yuanrong.decorator.function_proxy import FunctionProxy # noqa: E402 +from yuanrong.decorator.instance_proxy import ( # noqa: E402 InstanceCreator, InstanceProxy, MethodProxy, FunctionGroupHandler, FunctionGroupMethodProxy) __all__ = [ diff --git a/api/python/yr/accelerate/__init__.py b/api/python/yuanrong/accelerate/__init__.py similarity index 100% rename from api/python/yr/accelerate/__init__.py rename to api/python/yuanrong/accelerate/__init__.py diff --git a/api/python/yr/accelerate/executor.py b/api/python/yuanrong/accelerate/executor.py similarity index 97% rename from api/python/yr/accelerate/executor.py rename to api/python/yuanrong/accelerate/executor.py index 904016b..b13427e 100644 --- a/api/python/yr/accelerate/executor.py +++ b/api/python/yuanrong/accelerate/executor.py @@ -19,9 +19,9 @@ import traceback import threading import asyncio from typing import Dict, Tuple, Optional -from yr import log -from yr.accelerate.shm_broadcast import MessageQueue, ResponseStatus, STOP_EVENT -from yr.executor.instance_manager import InstanceManager +from yuanrong import log +from yuanrong.accelerate.shm_broadcast import MessageQueue, ResponseStatus, STOP_EVENT +from yuanrong.executor.instance_manager import InstanceManager ACCELERATE_WORKER = None diff --git a/api/python/yr/accelerate/shm_broadcast.py b/api/python/yuanrong/accelerate/shm_broadcast.py similarity index 98% rename from api/python/yr/accelerate/shm_broadcast.py rename to api/python/yuanrong/accelerate/shm_broadcast.py index edcad1c..7d98f82 100644 --- a/api/python/yr/accelerate/shm_broadcast.py +++ b/api/python/yuanrong/accelerate/shm_broadcast.py @@ -23,8 +23,8 @@ from contextlib import contextmanager, asynccontextmanager from typing import Optional from enum import IntEnum from dataclasses import dataclass -from yr import log -import yr +from yuanrong import log +import yuanrong STOP_EVENT = threading.Event() USE_SCHED_YIELD = ((sys.version_info[:3] >= (3, 11, 1)) @@ -67,14 +67,14 @@ class ShmRingBuffer: self.data_offset = 0 self.metadata_offset = self.max_chunk_bytes * self.max_chunks if name is None: - obj_id, shared_memory = yr.runtime_holder.global_runtime.get_runtime().create_buffer( + obj_id, shared_memory = yuanrong.runtime_holder.global_runtime.get_runtime().create_buffer( self.total_bytes_of_buffer) self.name = obj_id self.shared_memory = shared_memory self.shared_memory.get_buf()[:] = bytes(len(self.shared_memory.get_buf())) else: self.name = name - self.shared_memory = yr.runtime_holder.global_runtime.get_runtime().get_buffer(name) + self.shared_memory = yuanrong.runtime_holder.global_runtime.get_runtime().get_buffer(name) def handle(self): """message queue handle""" diff --git a/api/python/yr/affinity.py b/api/python/yuanrong/affinity.py similarity index 100% rename from api/python/yr/affinity.py rename to api/python/yuanrong/affinity.py diff --git a/api/python/yr/apis.py b/api/python/yuanrong/apis.py similarity index 85% rename from api/python/yr/apis.py rename to api/python/yuanrong/apis.py index e029809..df01961 100644 --- a/api/python/yr/apis.py +++ b/api/python/yuanrong/apis.py @@ -22,26 +22,26 @@ import logging import os from typing import List, Dict, Optional, Tuple, Union -from yr.libruntime_pb2 import LanguageType - -from yr import log, runtime_holder -from yr.code_manager import CodeManager -from yr.common import constants, utils -from yr.config import ClientInfo, Config, InvokeOptions -from yr.config_manager import ConfigManager -from yr.decorator import function_proxy, instance_proxy -from yr.executor.executor import Executor -from yr.fnruntime import Consumer, Producer, auto_get_cluster_access_info -from yr.object_ref import ObjectRef -from yr.resource_group_ref import RgObjectRef -from yr.runtime import ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, GetParams -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.decorator.function_proxy import FunctionProxy -from yr.decorator.instance_proxy import InstanceCreator, InstanceProxy -from yr.common.utils import CrossLanguageInfo -from yr.resource_group import ResourceGroup - -from yr.serialization import Serialization +from yuanrong.libruntime_pb2 import LanguageType + +from yuanrong import log, runtime_holder +from yuanrong.code_manager import CodeManager +from yuanrong.common import constants, utils +from yuanrong.config import ClientInfo, Config, InvokeOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.executor.executor import Executor +from yuanrong.fnruntime import Consumer, Producer, auto_get_cluster_access_info +from yuanrong.object_ref import ObjectRef +from yuanrong.resource_group_ref import RgObjectRef +from yuanrong.runtime import ExistenceOpt, WriteMode, CacheType, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.decorator.function_proxy import FunctionProxy +from yuanrong.decorator.instance_proxy import InstanceCreator, InstanceProxy +from yuanrong.common.utils import CrossLanguageInfo +from yuanrong.resource_group import ResourceGroup + +from yuanrong.serialization import Serialization __g_is_init = False _MAX_INT = 0x7FFFFFFF @@ -136,19 +136,19 @@ def init(conf: Config = None) -> ClientInfo: The context information of this invocation. Data type is ClientInfo. Raises: - RuntimeError: If yr.init is called more than once. + RuntimeError: If yuanrong.init is called more than once. TypeError: If the parameter type is incorrect. ValueError: If the parameter value is incorrect. Example: - >>> import yr + >>> import yuanrong >>> - >>> conf = yr.Config() - >>> yr.init(conf) + >>> conf = yuanrong.Config() + >>> yuanrong.init(conf) """ if is_initialized() and ConfigManager().is_driver: - raise RuntimeError("yr.init cannot be called twice") + raise RuntimeError("yuanrong.init cannot be called twice") conf = Config() if conf is None else conf @@ -184,16 +184,16 @@ def finalize() -> None: Raises: - RuntimeError: This exception will be thrown if ``finalize`` is called without initializing ``yr``. + RuntimeError: This exception will be thrown if ``finalize`` is called without initializing ``yuanrong``. Returns: None. Examples: - >>> import yr - >>> conf = yr.Config() - >>> yr.init(conf) - >>> yr.finalize() + >>> import yuanrong + >>> conf = yuanrong.Config() + >>> yuanrong.init(conf) + >>> yuanrong.finalize() """ global __g_is_init if not __g_is_init: @@ -218,7 +218,7 @@ def put(obj: object, create_param: CreateParam = CreateParam()) -> ObjectRef: Put an object to datasystem. Note: - 1. this method should be used after `yr.init()`. + 1. this method should be used after `yuanrong.init()`. 2. If the type of put is memoryview, bytearray or bytes, serialization is omitted at this time. 3. If the object passed to put() is of type memoryview, bytearray, or bytes, its length must not be ``0``. @@ -233,25 +233,25 @@ def put(obj: object, create_param: CreateParam = CreateParam()) -> ObjectRef: ValueError: If the input `obj` is `None` or a zero-length `bytes`, `bytearray`, or `memoryview` object. TypeError: If the input obj is already an `ObjectRef`. TypeError: If the input obj is not serializable, e.g. `thread.RLock`. - RuntimeError: Call `yr.put()` before `yr.init()`. + RuntimeError: Call `yuanrong.put()` before `yuanrong.init()`. RuntimeError: Failed to put to datasystem. Examples: - >>> import yr - >>> yr.init() - >>> param = yr.CreateParam() - >>> param.cache_type = yr.CacheType.DISK + >>> import yuanrong + >>> yuanrong.init() + >>> param = yuanrong.CreateParam() + >>> param.cache_type = yuanrong.CacheType.DISK >>> bs = bytes(0) >>> mem = memoryview(bytes(100)) - >>> obj_ref2 = yr.put(mem) - >>> print(yr.get(obj_ref2)) + >>> obj_ref2 = yuanrong.put(mem) + >>> print(yuanrong.get(obj_ref2)) >>> # The final print output is a memoryview pointer. >>> byte_array = bytearray(20) - >>> obj_ref3 = yr.put(byte_array) - >>> print(yr.get(obj_ref3)) + >>> obj_ref3 = yuanrong.put(byte_array) + >>> print(yuanrong.get(obj_ref3)) >>> # The final print output is a memoryview pointer. - >>> obj_ref4 = yr.put(100) - >>> print(yr.get(obj_ref4)) + >>> obj_ref4 = yuanrong.put(100) + >>> print(yuanrong.get(obj_ref4)) """ if obj is None or (isinstance(obj, (bytes, bytearray, memoryview)) and len(obj) == 0): raise ValueError("value is None or has zero length") @@ -271,7 +271,7 @@ def get(obj_refs: Union["ObjectRef", List, "RgObjectRef"], timeout: int = consta The interface call will block until the object's value is obtained or a timeout occurs. Note: - yr.get() uniformly returns a memoryview pointer for bytes, bytearray, and memoryview types. + yuanrong.get() uniformly returns a memoryview pointer for bytes, bytearray, and memoryview types. Args: obj_refs (ObjectRef, List[ObjectRef]): The object_ref of the object in the data system. @@ -292,17 +292,17 @@ def get(obj_refs: Union["ObjectRef", List, "RgObjectRef"], timeout: int = consta TimeoutError: If the results of all object references cannot be obtained within the specified timeout period. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke() + >>> @yuanrong.invoke() >>> def add(a, b): ... return a + b >>> obj_ref_1 = add.invoke(1, 2) >>> obj_ref_2 = add.invoke(3, 4) - >>> result = yr.get([obj_ref_1, obj_ref_2], timeout=-1) + >>> result = yuanrong.get([obj_ref_1, obj_ref_2], timeout=-1) >>> print(result) - >>> yr.finalize() + >>> yuanrong.finalize() """ if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: @@ -355,12 +355,12 @@ def wait(obj_refs: Union[ObjectRef, List[ObjectRef]], wait_num: int = 1, ValueError: If the input parameter is incorrect. Examples: - >>> import yr + >>> import yuanrong >>> import time >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo(a): ... time.sleep(a) ... return "sleep:", a @@ -369,12 +369,12 @@ def wait(obj_refs: Union[ObjectRef, List[ObjectRef]], wait_num: int = 1, >>> >>> wait_num = 3 >>> timeout = 10 - >>> result = yr.wait(res, wait_num, timeout) + >>> result = yuanrong.wait(res, wait_num, timeout) >>> print("ready_list = ", result[0], "unready_list = ", result[1]) - >>> print(yr.get(result[0])) + >>> print(yuanrong.get(result[0])) [('sleep:', 0), ('sleep:', 1)] >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if timeout is None: timeout = -1 @@ -438,16 +438,16 @@ def cancel(obj_refs: Union[ObjectRef, List[ObjectRef]], allow_force: bool = _DEF Examples: >>> import time - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke >>> def func(): >>> time.sleep(100) >>> >>> ret = func.invoke() - >>> yr.cancel(ret) - >>> yr.finalize() + >>> yuanrong.cancel(ret) + >>> yuanrong.finalize() """ if isinstance(obj_refs, ObjectRef): obj_refs = [obj_refs] @@ -481,28 +481,28 @@ def invoke(*args, **kwargs) -> function_proxy.FunctionProxy: Examples: Simple invocation example: - >>> import yr - >>> yr.init() - >>> @yr.invoke + >>> import yuanrong + >>> yuanrong.init() + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> ret = add.invoke(1, 2) - >>> print(yr.get(ret)) - >>> yr.finalize() + >>> print(yuanrong.get(ret)) + >>> yuanrong.finalize() Function invocation example: - >>> import yr - >>> yr.init() - >>> @yr.invoke + >>> import yuanrong + >>> yuanrong.init() + >>> @yuanrong.invoke ... def func1(a): ... return a + " func1" - >>> @yr.invoke + >>> @yuanrong.invoke ... def func2(a): - ... return yr.get(func1.invoke(a)) + " func2" + ... return yuanrong.get(func1.invoke(a)) + " func2" >>> ret = func2.invoke("hello") - >>> print(yr.get(ret)) - >>> yr.finalize() + >>> print(yuanrong.get(ret)) + >>> yuanrong.finalize() """ if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): return function_proxy.make_decorator()(args[0]) @@ -518,7 +518,7 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: Args: class (class): The class that needs to be remotely invoked. - invoke_options (yr.InvokeOptions): Invocation parameters. + invoke_options (yuanrong.InvokeOptions): Invocation parameters. Returns: The creator of the decorated class. @@ -529,10 +529,10 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: Example: Simple invocation example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... def add(self, a): @@ -541,18 +541,18 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: ... return self.sum >>> >>> ins = Instance.invoke() - >>> yr.get(ins.add.invoke(1)) - >>> print(yr.get(ins.get.invoke())) + >>> yuanrong.get(ins.add.invoke(1)) + >>> print(yuanrong.get(ins.get.invoke())) 1 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() Function invocation example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... def __init__(self): ... self.sum = 0 @@ -561,22 +561,22 @@ def instance(*args, **kwargs) -> instance_proxy.InstanceCreator: ... def get(self): ... return self.sum - >>> @yr.instance + >>> @yuanrong.instance ... class Instance2: ... def __init__(self): ... self.ins = Instance.invoke() ... def add(self, a): ... return self.ins.add.invoke(a) ... def get(self): - ... return yr.get(self.ins.get.invoke()) + ... return yuanrong.get(self.ins.get.invoke()) >>> >>> ins = Instance2.invoke() - >>> yr.get(ins.add.invoke(2)) - >>> print(yr.get(ins.get.invoke())) + >>> yuanrong.get(ins.add.invoke(2)) + >>> print(yuanrong.get(ins.get.invoke())) 2 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): @@ -601,10 +601,10 @@ def method(*args, **kwargs): TypeError: If the type of the input parameters is incorrect. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... @@ -614,19 +614,19 @@ def method(*args, **kwargs): ... def get(self): ... return self.sum ... - ... @yr.method(return_nums=2) + ... @yuanrong.method(return_nums=2) ... def detail(self, a, b): ... return a, b ... >>> ins = Instance.invoke() >>> res1, res2 = ins.detail.invoke(0, 1) - >>> print("detail result1:", yr.get(res1)) + >>> print("detail result1:", yuanrong.get(res1)) detail result1: 0 - >>> print("detail result2:", yr.get(res2)) + >>> print("detail result2:", yuanrong.get(res2)) detail result2: 1 >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if "concurrency_group" in kwargs and len(args) == 0: kwargs.pop("concurrency_group") @@ -821,12 +821,12 @@ def kv_write(key: str, value: bytes, existence: ExistenceOpt = ExistenceOpt.NONE RuntimeError: If the data fails to be written to the data system. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> yr.kv_write("kv-key", b"value1", yr.ExistenceOpt.NONE, yr.WriteMode.NONE_L2_CACHE, 0, yr.CacheType.MEMORY) + >>> yuanrong.kv_write("kv-key", b"value1", yuanrong.ExistenceOpt.NONE, yuanrong.WriteMode.NONE_L2_CACHE, 0, yuanrong.CacheType.MEMORY) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ set_param = SetParam() set_param.existence = existence @@ -857,18 +857,18 @@ def kv_write_with_param(key: str, value: bytes, set_param: SetParam) -> None: RuntimeError: If the data fails to be written to the data system. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> set_param = yr.SetParam() - >>> set_param.existence = yr.ExistenceOpt.NX - >>> set_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> set_param = yuanrong.SetParam() + >>> set_param.existence = yuanrong.ExistenceOpt.NX + >>> set_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> set_param.ttl_second = 10 - >>> set_param.cache_type = yr.CacheType.DISK - >>> yr.kv_write_with_param("kv-key", b"value1", set_param) + >>> set_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_write_with_param("kv-key", b"value1", set_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ runtime_holder.global_runtime.get_runtime().kv_write(key, value, set_param) @@ -895,18 +895,18 @@ def kv_m_write_tx(keys: List[str], values: List[bytes], m_set_param: MSetParam = If data writing to the data system fails. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> mset_param = yr.MSetParam() - >>> mset_param.existence = yr.ExistenceOpt.NX - >>> mset_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> mset_param = yuanrong.MSetParam() + >>> mset_param.existence = yuanrong.ExistenceOpt.NX + >>> mset_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> mset_param.ttl_second = 100 - >>> mset_param.cache_type = yr.CacheType.DISK - >>> yr.kv_m_write_tx(["key1", "key2"], [b"value1", b"value2"], mset_param) + >>> mset_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_m_write_tx(["key1", "key2"], [b"value1", b"value2"], mset_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if len(keys) != len(values): raise ValueError( @@ -938,7 +938,7 @@ def kv_read( RuntimeError: If data retrieval from the data system fails. Example: - >>> v1 = yr.kv_read("kv-key") + >>> v1 = yuanrong.kv_read("kv-key") """ is_single_obj = isinstance(key, str) rets = runtime_holder.global_runtime.get_runtime().kv_read(key, timeout) @@ -966,18 +966,18 @@ def kv_set(key: str, value: bytes, set_param: SetParam = SetParam()) -> None: RuntimeError: If the data writing to the data system fails. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> # The worker startup parameters need to be configured with shared_disk_directory and shared_disk_size_mb; >>> # otherwise, this example will result in an error - >>> set_param = yr.SetParam() - >>> set_param.existence = yr.ExistenceOpt.NX - >>> set_param.write_mode = yr.WriteMode.NONE_L2_CACHE_EVICT + >>> set_param = yuanrong.SetParam() + >>> set_param.existence = yuanrong.ExistenceOpt.NX + >>> set_param.write_mode = yuanrong.WriteMode.NONE_L2_CACHE_EVICT >>> set_param.ttl_second = 10 - >>> set_param.cache_type = yr.CacheType.DISK - >>> yr.kv_set("kv-key", b"value1", set_param) + >>> set_param.cache_type = yuanrong.CacheType.DISK + >>> yuanrong.kv_set("kv-key", b"value1", set_param) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ runtime_holder.global_runtime.get_runtime().kv_write(key, value, set_param) @@ -1004,7 +1004,7 @@ def kv_get( RuntimeError: If data retrieval from the data system fails. Example: - >>> v1 = yr.kv_get("kv-key") + >>> v1 = yuanrong.kv_get("kv-key") """ if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: raise ValueError( @@ -1040,12 +1040,12 @@ def kv_get_with_param(keys: List[str], get_params: GetParams, timeout: int = con RuntimeError: If data retrieval from the data system fails. Example: - >>> get_param = yr.GetParam() + >>> get_param = yuanrong.GetParam() >>> get_param.offset = 0 >>> get_param.size = 0 - >>> params = yr.GetParams() + >>> params = yuanrong.GetParams() >>> params.get_params = [get_param] - >>> v1 = yr.kv_get_with_param(["kv-key"], params, 10) + >>> v1 = yuanrong.kv_get_with_param(["kv-key"], params, 10) """ if timeout < constants.NO_LIMIT: raise ValueError( @@ -1074,8 +1074,8 @@ def kv_del(key: Union[str, List[str]]) -> None: RuntimeError: If data deletion from the data system fails. Example: - >>> yr.kv_write("kv-key", b"value1", yr.ExistenceOpt.NONE, yr.WriteMode.NONE_L2_CACHE, 0) # doctest: +SKIP - >>> yr.kv_del("kv-key") + >>> yuanrong.kv_write("kv-key", b"value1", yuanrong.ExistenceOpt.NONE, yuanrong.WriteMode.NONE_L2_CACHE, 0) # doctest: +SKIP + >>> yuanrong.kv_del("kv-key") """ runtime_holder.global_runtime.get_runtime().kv_del(key) @@ -1101,7 +1101,7 @@ def save_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: Example: - >>> @yr.instance + >>> @yuanrong.instance ... class Counter: ... def __init__(self): ... self.cnt = 0 @@ -1114,20 +1114,20 @@ def save_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: ... return self.cnt ... ... def save(self, timeout=30): - ... yr.save_state(timeout) + ... yuanrong.save_state(timeout) ... ... def load(self, timeout=30): - ... yr.load_state(timeout) + ... yuanrong.load_state(timeout) ... >>> counter = Counter.invoke() - >>> print(f"member value before save state: {yr.get(counter.get.invoke())}") + >>> print(f"member value before save state: {yuanrong.get(counter.get.invoke())}") >>> counter.save.invoke() >>> >>> counter.add.invoke() - >>> print(f"member value after add one: {yr.get(counter.get.invoke())}") + >>> print(f"member value after add one: {yuanrong.get(counter.get.invoke())}") >>> >>> counter.load.invoke() - >>> print(f"member value after load state(back to 0): {yr.get(counter.get.invoke())}") + >>> print(f"member value after load state(back to 0): {yuanrong.get(counter.get.invoke())}") """ remote_runtime = ConfigManager().in_cluster and not ConfigManager().is_driver if not remote_runtime: @@ -1163,7 +1163,7 @@ def load_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: Example: - >>> @yr.instance + >>> @yuanrong.instance ... class Counter: ... def __init__(self): ... self.cnt = 0 @@ -1176,22 +1176,22 @@ def load_state(timeout_sec: int = _DEFAULT_SAVE_LOAD_STATE_TIMEOUT) -> None: ... return self.cnt ... ... def save(self, timeout=30): - ... yr.save_state(timeout) + ... yuanrong.save_state(timeout) ... ... def load(self, timeout=30): - ... yr.load_state(timeout) + ... yuanrong.load_state(timeout) ... >>> counter = Counter.invoke() - >>> print(f"member value before save state: {yr.get(counter.get.invoke())}") + >>> print(f"member value before save state: {yuanrong.get(counter.get.invoke())}") member value before save state: 0 >>> counter.save.invoke() >>> >>> counter.add.invoke() - >>> print(f"member value after add one: {yr.get(counter.get.invoke())}") + >>> print(f"member value after add one: {yuanrong.get(counter.get.invoke())}") member value after add one: 1 >>> >>> counter.load.invoke() - >>> print(f"member value after load state(back to 0): {yr.get(counter.get.invoke())}") + >>> print(f"member value after load state(back to 0): {yuanrong.get(counter.get.invoke())}") member value after load state(back to 0): 0 """ remote_runtime = ConfigManager().in_cluster and not ConfigManager().is_driver @@ -1226,7 +1226,7 @@ def get_instance(name: str, namespace: str = "", timeout: int = 60) -> instance_ TimeoutError: If a timeout occurs. Examples: - >>> yr.get_instance("name") + >>> yuanrong.get_instance("name") """ if not isinstance(name, str): @@ -1261,7 +1261,7 @@ def resources() -> List[dict]: """ Get the resource information of nodes in the cluster. - When requesting resource information, you need to configure `master_addr_list` in `yr.Config`. + When requesting resource information, you need to configure `master_addr_list` in `yuanrong.Config`. Returns: list[dict], The resource information of nodes in the cluster. The dict contains the following keys, @@ -1275,15 +1275,15 @@ def resources() -> List[dict]: RuntimeError: If the information retrieval from the functionsystem master fails. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> res = yr.resources() + >>> res = yuanrong.resources() >>> print(res) [{'id': 'function-agent-172.17.0.2-25742','status': 0, 'capacity': {'CPU': 1000.0, 'Memory': 8192.0}, 'allocatable': {'CPU': 500.0, 'Memory': 4096.0}}] >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ if ConfigManager().local_mode: raise RuntimeError("resources is not supported in local mode") @@ -1295,11 +1295,11 @@ def get_node_ip_address(): """ Obtain the node ip. Examples: - >>> import yr - >>> yr.init() - >>> node_ip = yr.get_node_ip_address() + >>> import yuanrong + >>> yuanrong.init() + >>> node_ip = yuanrong.get_node_ip_address() >>> print(node_ip) - >>> yr.finalize() + >>> yuanrong.finalize() """ return runtime_holder.global_runtime.get_runtime().get_node_ip_address() @@ -1362,9 +1362,9 @@ def create_resource_group(bundles: List[Dict[str, float]], name: Optional[str] = RuntimeError: If the resource group name is invalid. Examples: - >>> rg1 = yr.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}]) + >>> rg1 = yuanrong.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}]) >>> - >>> rg2 = yr.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg2 = yuanrong.create_resource_group([{"NPU/Ascend910B4/count":1},{"CPU":2000,"Memory":2000}], "rgname") """ if not isinstance(bundles, list): raise TypeError(f"invalid bundles type, actual: {type(bundles)}, expect: list.") @@ -1394,10 +1394,10 @@ def remove_resource_group(resource_group: Union[str, ResourceGroup]): RuntimeError: The ResourceGroup name is invalid. Examples: - >>> yr.remove_resource_group("rgname") + >>> yuanrong.remove_resource_group("rgname") >>> - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") - >>> yr.remove_resource_group(rg) + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> yuanrong.remove_resource_group(rg) """ name = resource_group if isinstance(resource_group, ResourceGroup): @@ -1424,7 +1424,7 @@ class cpp_instance_class: .. code-block:: cpp #include - #include "yr/yr.h" + #include "yuanrong/yuanrong.h" class Counter { public: int count; @@ -1450,19 +1450,19 @@ class cpp_instance_class: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> cpp_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-cpp:$latest" + ... "function:0-yuanrong-defaultservice-cpp:$latest" ... ) - >>> counter_class = yr.cpp_instance_class("Counter", "Counter::FactoryCreate", cpp_function_urn) - >>> opt = yr.InvokeOptions(cpu=1000, memory=1024) + >>> counter_class = yuanrong.cpp_instance_class("Counter", "Counter::FactoryCreate", cpp_function_urn) + >>> opt = yuanrong.InvokeOptions(cpu=1000, memory=1024) >>> ins = counter_class.options(opt).invoke(11) >>> result = ins.Add.invoke(9) - >>> yr.get(result) + >>> yuanrong.get(result) >>> ins.terminate() - >>> yr.finalize() + >>> yuanrong.finalize() """ self.__class_name__ = class_name self.__factory_name__ = factory_name @@ -1531,7 +1531,7 @@ def cpp_function(function_name: str, function_urn: str) -> FunctionProxy: Examples: .. code-block:: cpp - #include "yr/yr.h" + #include "yuanrong/yuanrong.h" int Square(int x) { return x * x; @@ -1542,16 +1542,16 @@ def cpp_function(function_name: str, function_urn: str) -> FunctionProxy: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> cpp_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-cpp:$latest" + ... "function:0-yuanrong-defaultservice-cpp:$latest" ... ) - >>> square_func = yr.cpp_function("Square", cpp_function_urn) + >>> square_func = yuanrong.cpp_function("Square", cpp_function_urn) >>> result = square_func.invoke(5) - >>> print(yr.get(result)) - >>> yr.finalize() + >>> print(yuanrong.get(result)) + >>> yuanrong.finalize() """ return function_proxy.make_cross_language_function_proxy(function_name, function_urn, LanguageType.Cpp) @@ -1594,15 +1594,15 @@ def java_function(class_name: str, function_name: str, function_urn: str) -> Fun .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> java_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-java:$latest" + ... "function:0-yuanrong-defaultservice-java:$latest" ... ) - >>> java_add = yr.java_function("com.yuanrong.demo.PlusOne", "PlusOne", java_function_urn) + >>> java_add = yuanrong.java_function("com.yuanrong.demo.PlusOne", "PlusOne", java_function_urn) >>> result = java_add.invoke(1) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ function_key = utils.get_function_from_urn(function_urn) @@ -1650,22 +1650,22 @@ def java_instance_class(class_name: str, function_urn: str) -> InstanceCreator: .. code:: python - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> java_function_urn = ( ... "sn:cn:yrk:12345678901234561234567890123456:" - ... "function:0-yr-defaultservice-java:$latest" + ... "function:0-yuanrong-defaultservice-java:$latest" ... ) >>> - >>> java_instance = yr.java_instance_class("com.yuanrong.demo.Counter", java_function_urn).invoke(1) + >>> java_instance = yuanrong.java_instance_class("com.yuanrong.demo.Counter", java_function_urn).invoke(1) >>> res = java_instance.Add.invoke(5) - >>> print(yr.get(res)) + >>> print(yuanrong.get(res)) >>> >>> res = java_instance.Get.invoke() - >>> print(yr.get(res)) + >>> print(yuanrong.get(res)) >>> >>> java_instance.terminate() - >>> yr.finalize() + >>> yuanrong.finalize() """ function_key = utils.get_function_from_urn(function_urn) @@ -1701,11 +1701,11 @@ def list_named_instances(all_namespaces: bool = False): If an instance is configured with a namespace, the namespace and instance name will be connected using a `-`. Examples: - >>> import yr - >>> yr.init() - >>> named_instances = yr.list_named_instances() + >>> import yuanrong + >>> yuanrong.init() + >>> named_instances = yuanrong.list_named_instances() >>> print(named_instances) - >>> yr.finalize() + >>> yuanrong.finalize() """ all_actors = runtime_holder.global_runtime.get_runtime().query_named_instances() if all_namespaces: diff --git a/api/python/yr/cluster_mode_runtime.py b/api/python/yuanrong/cluster_mode_runtime.py similarity index 96% rename from api/python/yr/cluster_mode_runtime.py rename to api/python/yuanrong/cluster_mode_runtime.py index f16d791..f81f5b3 100644 --- a/api/python/yr/cluster_mode_runtime.py +++ b/api/python/yuanrong/cluster_mode_runtime.py @@ -19,19 +19,19 @@ import logging from typing import Any, Dict, List, Tuple, Union, Callable -from yr.exception import YRInvokeError -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.common.types import InvokeArg, GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.config_manager import ConfigManager -from yr.fnruntime import Consumer, Fnruntime, Producer, SharedBuffer -from yr.libruntime_pb2 import ApiType, FunctionMeta -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData -from yr.object_ref import ObjectRef -from yr.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams -from yr.serialization import Serialization -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.accelerate.shm_broadcast import Handle +from yuanrong.exception import YRInvokeError +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.common.types import InvokeArg, GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.fnruntime import Consumer, Fnruntime, Producer, SharedBuffer +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.serialization import Serialization +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.accelerate.shm_broadcast import Handle _logger = logging.getLogger(__name__) diff --git a/api/python/yr/code_manager.py b/api/python/yuanrong/code_manager.py similarity index 97% rename from api/python/yr/code_manager.py rename to api/python/yuanrong/code_manager.py index c85afed..74b20e9 100644 --- a/api/python/yr/code_manager.py +++ b/api/python/yuanrong/code_manager.py @@ -23,12 +23,12 @@ import sys import threading from typing import Callable, List -from yr import log -from yr.common import constants, utils -from yr.common.singleton import Singleton -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.functionsdk.error_code import FaasErrorCode -from yr.libruntime_pb2 import LanguageType +from yuanrong import log +from yuanrong.common import constants, utils +from yuanrong.common.singleton import Singleton +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.functionsdk.error_code import FaasErrorCode +from yuanrong.libruntime_pb2 import LanguageType _DEFAULT_ADMIN_FUNC_PATH = "/adminfunc/" _MAX_FAAS_ENTRY_NUMS = 3 diff --git a/api/python/yr/common/__init__.py b/api/python/yuanrong/common/__init__.py similarity index 100% rename from api/python/yr/common/__init__.py rename to api/python/yuanrong/common/__init__.py diff --git a/api/python/yr/common/constants.py b/api/python/yuanrong/common/constants.py similarity index 100% rename from api/python/yr/common/constants.py rename to api/python/yuanrong/common/constants.py diff --git a/api/python/yr/common/singleton.py b/api/python/yuanrong/common/singleton.py similarity index 100% rename from api/python/yr/common/singleton.py rename to api/python/yuanrong/common/singleton.py diff --git a/api/python/yr/common/types.py b/api/python/yuanrong/common/types.py similarity index 100% rename from api/python/yr/common/types.py rename to api/python/yuanrong/common/types.py diff --git a/api/python/yr/common/utils.py b/api/python/yuanrong/common/utils.py similarity index 99% rename from api/python/yr/common/utils.py rename to api/python/yuanrong/common/utils.py index e67a6a2..cd931a2 100644 --- a/api/python/yr/common/utils.py +++ b/api/python/yuanrong/common/utils.py @@ -33,9 +33,9 @@ from typing import Dict import asyncio import cloudpickle -from yr import log -from yr.common import constants -from yr.libruntime_pb2 import LanguageType, FunctionMeta +from yuanrong import log +from yuanrong.common import constants +from yuanrong.libruntime_pb2 import LanguageType, FunctionMeta try: import uvloop @@ -45,7 +45,7 @@ except ImportError: _URN_SEPARATOR = ":" _NO_ORDER_SUFFIX = "-x" -_OBJECT_ID_PREFIX = "yr-api-obj-" +_OBJECT_ID_PREFIX = "yuanrong-api-obj-" _TRACE_ID = "-trace-" _JOB_ID = "" _RGROUP_PREFIX = "rgroup-" diff --git a/api/python/yr/compiled_dag_ref.py b/api/python/yuanrong/compiled_dag_ref.py similarity index 92% rename from api/python/yr/compiled_dag_ref.py rename to api/python/yuanrong/compiled_dag_ref.py index 6893416..c69321f 100644 --- a/api/python/yr/compiled_dag_ref.py +++ b/api/python/yuanrong/compiled_dag_ref.py @@ -17,8 +17,8 @@ import asyncio from typing import Any, List, Optional -import yr -from yr.exception import ( +import yuanrong +from yuanrong.exception import ( GetTimeoutError, YRChannelError, YRChannelTimeoutError, @@ -54,17 +54,17 @@ class CompiledDAGRef: A reference to a compiled DAG execution result. This is a subclass of ObjectRef and resembles ObjectRef. For example, - similar to ObjectRef, yr.get() can be called on it to retrieve the result. + similar to ObjectRef, yuanrong.get() can be called on it to retrieve the result. However, there are several major differences: - 1. yr.get() can only be called once per CompiledDAGRef. - 2. yr.wait() is not supported. + 1. yuanrong.get() can only be called once per CompiledDAGRef. + 2. yuanrong.wait() is not supported. 3. CompiledDAGRef cannot be copied, deep copied, or pickled. 4. CompiledDAGRef cannot be passed as an argument to another task. """ def __init__( self, - dag: "yr.dag.CompiledDAG", + dag: "yuanrong.dag.CompiledDAG", execution_index: int, channel_index: Optional[int] = None, ): @@ -87,7 +87,7 @@ class CompiledDAGRef: self._dag = dag self._execution_index = execution_index self._channel_index = channel_index - # Whether yr.get() was called on this CompiledDAGRef. + # Whether yuanrong.get() was called on this CompiledDAGRef. self._yr_get_called = False self._dag_output_channels = dag.dag_output_channels @@ -116,7 +116,7 @@ class CompiledDAGRef: """ if self._yr_get_called: raise ValueError( - "yr.get() can only be called once " + "yuanrong.get() can only be called once " "on a CompiledDAGRef, and it was already called." ) @@ -131,7 +131,7 @@ class CompiledDAGRef: except YRChannelTimeoutError: raise except YRChannelError: - # If we get a channel error, we'd like to call yr.get() on + # If we get a channel error, we'd like to call yuanrong.get() on # the actor execution loop refs to check if this is a result # of task execution error which could not be passed down # (e.g., when a pure NCCL channel is used, it is only @@ -142,7 +142,7 @@ class CompiledDAGRef: # actor task refs have errors. actor_execution_loop_refs = list(self._dag.worker_task_refs.values()) try: - yr.get(actor_execution_loop_refs, timeout=10) + yuanrong.get(actor_execution_loop_refs, timeout=10) except GetTimeoutError as timeout_error: raise Exception( "Timed out when getting the actor execution loop exception. " @@ -161,20 +161,20 @@ class CompiledDAGFuture: """ A reference to a compiled DAG execution result, when executed with asyncio. This differs from CompiledDAGRef in that `await` must be called on the - future to get the result, instead of `yr.get()`. + future to get the result, instead of `yuanrong.get()`. This resembles async usage of ObjectRefs. For example, similar to ObjectRef, `await` can be called directly on the CompiledDAGFuture to retrieve the result. However, there are several major differences: 1. `await` can only be called once per CompiledDAGFuture. - 2. yr.wait() is not supported. + 2. yuanrong.wait() is not supported. 3. CompiledDAGFuture cannot be copied, deep copied, or pickled. 4. CompiledDAGFuture cannot be passed as an argument to another task. """ def __init__( self, - dag: "yr.dag.CompiledDAG", + dag: "yuanrong.dag.CompiledDAG", execution_index: int, fut: "asyncio.Future", channel_index: Optional[int] = None, diff --git a/api/python/yr/config.py b/api/python/yuanrong/config.py similarity index 96% rename from api/python/yr/config.py rename to api/python/yuanrong/config.py index 1b73779..dae788f 100644 --- a/api/python/yr/config.py +++ b/api/python/yuanrong/config.py @@ -15,14 +15,14 @@ # limitations under the License. """ -yr api config for user +yuanrong api config for user """ import dataclasses import json from dataclasses import asdict, dataclass, field from typing import Dict, List, Union, Optional, get_origin, Any from enum import Enum, IntEnum -from yr.affinity import Affinity +from yuanrong.affinity import Affinity _DEFAULT_CONNECTION_NUMS = 100 _DEFAULT_ENABLE_METRICS = False @@ -113,7 +113,7 @@ class Config: job_id: str = "" #: For out cluster https ssl. tls_config: UserTLSConfig = None - #: Auto start distribute-executor when `yr.init`, and auto stop distribute-executor when `yr.finalize`. + #: Auto start distribute-executor when `yuanrong.init`, and auto stop distribute-executor when `yuanrong.finalize`. #: default is ``False``. auto: bool = False #: When `auto=True` needed, use to define deployment detail. @@ -190,9 +190,9 @@ class Config: @dataclass class ClientInfo: """ - Use to store yr client info. + Use to store yuanrong client info. """ - #: Automatically generated when `yr.init` is called, a unique identifier for a task. + #: Automatically generated when `yuanrong.init` is called, a unique identifier for a task. job_id: str @@ -332,17 +332,17 @@ class InvokeOptions: """Use to set the invoke options. Examples: - >>> import yr + >>> import yuanrong >>> import time - >>> yr.init() - >>> opt = yr.InvokeOptions() + >>> yuanrong.init() + >>> opt = yuanrong.InvokeOptions() >>> opt.pod_labels["k1"] = "v1" - >>> @yr.invoke(invoke_options=opt) + >>> @yuanrong.invoke(invoke_options=opt) ... def func(): ... time.sleep(100) >>> ret = func.invoke() - >>> yr.get(ret) - >>> yr.finalize() + >>> yuanrong.get(ret) + >>> yuanrong.finalize() """ #: The size of the CPU required. Value Range is [300, 16000] and unit is m (milli-core). cpu: int = 500 @@ -384,9 +384,9 @@ class InvokeOptions: When used as a user-defined tag for metrics: - >>> import yr - >>> yr.init() - >>> opt = yr.InvokeOptions() + >>> import yuanrong + >>> yuanrong.init() + >>> opt = yuanrong.InvokeOptions() >>> opt.custom_extensions["YR_Metrics"] = "{\'endpoint\':\'127.0.0.1\', \'project_id\':\'my_project_id\'}" In Prometheus, select `metrics name` as `yr_app_instance_billing_invoke_latency`, and you can find the custom tag @@ -517,18 +517,18 @@ class InvokeOptions: * `working_dir` configure the code path of the job. * `env_vars` configure process-level environment variables. ``runtime_env = {"env_vars":{"OMP_NUM_THREADS": "32", "TF_WARNINGS": "none"}}`` - * `shared_dir` supports configuring a shared directory for some instance, with yr managing the lifecycle of this + * `shared_dir` supports configuring a shared directory for some instance, with yuanrong managing the lifecycle of this shared directory. `shared_dir` supports two fields: name and TTL. The name field only allows numbers, letters, "-", and "_". The TTL supports integers greater than 0 and less than INTMAX. ``runtime_env = {"shared_dir":{"name": "user_define", "TTL": 5}}`` * Constraints of `runtime_env`: * The keys supported by runtime_env are `conda`, `env_vars`, `pip`, `working_dir`. Other keys will not take effect and will not cause errors. - * Run the yr function with conda. The environment needs to have yr and its third-party dependencies. It is + * Run the yuanrong function with conda. The environment needs to have yuanrong and its third-party dependencies. It is recommended that users first create a conda environment and then specify it with `runtime_env`, for example: ``runtime_env = {"conda":"pytorch_p39"}`` * `runtime_env` supports creating and switching conda environments using configurations. The configuration needs - to install third-party dependencies for yr, for example: + to install third-party dependencies for yuanrong, for example: ``runtime_env["conda"] = {"name":"myenv","channels": ["conda-forge"], "dependencies": ["python=3.9", "msgpack-python=1.0.5", "protobuf", "libgcc-ng", "cloudpickle=2.0.0", "cython=3.0.10", "pyyaml=6.0.2"]}`` * The environment created using conda in `runtime_env` needs to be cleaned up by the user. @@ -545,7 +545,7 @@ class InvokeOptions: * `shared_dir` has the following constraints: 1. It is not recommended to configure different TTL for the same shared directory. 2. The minimum cleanup interval for shared directories is 5 seconds. - 3. When multiple yr Agents are deployed on the same node, each Agent must be configured with + 3. When multiple yuanrong Agents are deployed on the same node, each Agent must be configured with different root directory to prevent conflicts in shared directory management. """ diff --git a/api/python/yr/config/python-runtime-log.json b/api/python/yuanrong/config/python-runtime-log.json similarity index 100% rename from api/python/yr/config/python-runtime-log.json rename to api/python/yuanrong/config/python-runtime-log.json diff --git a/api/python/yr/config_manager.py b/api/python/yuanrong/config_manager.py similarity index 97% rename from api/python/yr/config_manager.py rename to api/python/yuanrong/config_manager.py index 186c517..1154415 100644 --- a/api/python/yr/config_manager.py +++ b/api/python/yuanrong/config_manager.py @@ -18,9 +18,9 @@ import logging -from yr.common import utils -from yr.common.singleton import Singleton -from yr.config import Config, DeploymentConfig, MetaConfig, MetaFunctionID +from yuanrong.common import utils +from yuanrong.common.singleton import Singleton +from yuanrong.config import Config, DeploymentConfig, MetaConfig, MetaFunctionID _DEFAULT_CLUSTER_PORT = "31222" _DEFAULT_IN_CLUSTER_CLUSTER_PORT = "21003" @@ -51,7 +51,7 @@ class ConfigManager: server_address: System cluster address. ds_address: DataSystem address. is_driver: only False when initialize in runtime - log_level: yr api log level, default: WARNING + log_level: yuanrong api log level, default: WARNING """ def __init__(self): @@ -230,7 +230,7 @@ class ConfigManager: Init the ConfigManager Args: - :param conf: The yr api config which set by user. + :param conf: The yuanrong api config which set by user. :param is_init: init state """ job_id = conf.job_id if conf.job_id != "" else utils.generate_job_id() diff --git a/api/python/yr/decorator/__init__.py b/api/python/yuanrong/decorator/__init__.py similarity index 100% rename from api/python/yr/decorator/__init__.py rename to api/python/yuanrong/decorator/__init__.py diff --git a/api/python/yr/decorator/function_proxy.py b/api/python/yuanrong/decorator/function_proxy.py similarity index 90% rename from api/python/yr/decorator/function_proxy.py rename to api/python/yuanrong/decorator/function_proxy.py index c2049cc..5f977a5 100644 --- a/api/python/yr/decorator/function_proxy.py +++ b/api/python/yuanrong/decorator/function_proxy.py @@ -24,17 +24,17 @@ import types from functools import wraps from typing import List, Union -import yr -from yr import signature -from yr.config import function_group_enabled -from yr.common.types import GroupInfo -from yr.common import utils -from yr.common.utils import CrossLanguageInfo, ObjectDescriptor -from yr.config import InvokeOptions -from yr.libruntime_pb2 import FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.generator import ObjectRefGenerator +import yuanrong +from yuanrong import signature +from yuanrong.config import function_group_enabled +from yuanrong.common.types import GroupInfo +from yuanrong.common import utils +from yuanrong.common.utils import CrossLanguageInfo, ObjectDescriptor +from yuanrong.config import InvokeOptions +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.generator import ObjectRefGenerator _logger = logging.getLogger(__name__) @@ -44,18 +44,18 @@ class FunctionProxy: Use to decorate user function. Examples: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> >>> ret = add.invoke(1, 2) - >>> print(yr.get(ret)) + >>> print(yuanrong.get(ret)) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ def __init__(self, func, cross_language_info=None, invoke_options=None, return_nums=None, initializer=None): @@ -141,19 +141,19 @@ class FunctionProxy: The FunctionProxy object itself. Data type is FunctionProxy. Examples: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def add(a, b): ... return a + b >>> - >>> opt = yr.InvokeOptions(cpu=1000, memory=1024) + >>> opt = yuanrong.InvokeOptions(cpu=1000, memory=1024) >>> ret = add.options(opt).invoke(1, 2) - >>> print(yr.get(ret)) + >>> print(yuanrong.get(ret)) >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ for method in ("check_options_valid", "check_options_range"): @@ -210,7 +210,7 @@ class FunctionProxy: return self._options_wrapper(opts) def _invoke_function(self, opts: InvokeOptions, func, args=None, kwargs=None) -> Union[ - "yr.ObjectRef", List["yr.ObjectRef"]]: + "yuanrong.ObjectRef", List["yuanrong.ObjectRef"]]: """ The real realization of the invoke function @@ -232,12 +232,12 @@ class FunctionProxy: or not global_runtime.get_runtime().is_object_existing_in_local( self._code_ref.id )): - self._code_ref = yr.put(func) + self._code_ref = yuanrong.put(func) _logger.debug("[Reference Counting] put code with id = %s, functionName = %s", self._code_ref.id, func.__qualname__) with self._lock: if self._initializer and self._initializer_code_ref is None: - self._initializer_code_ref = yr.put(self._initializer) + self._initializer_code_ref = yuanrong.put(self._initializer) initializer_code_id = self._initializer_code_ref if self._initializer_code_ref is not None else "" func_meta = FunctionMeta(functionID=function_id, # if designated_urn is not set, @@ -305,7 +305,7 @@ def make_decorator(invoke_options=None, return_nums=None, initializer=None) -> c def decorator(func): if isinstance(func, types.FunctionType): return FunctionProxy(func, invoke_options=invoke_options, return_nums=return_nums, initializer=initializer) - raise RuntimeError("@yr.invoke decorator must be applied to a function") + raise RuntimeError("@yuanrong.invoke decorator must be applied to a function") return decorator diff --git a/api/python/yr/decorator/instance_proxy.py b/api/python/yuanrong/decorator/instance_proxy.py similarity index 96% rename from api/python/yr/decorator/instance_proxy.py rename to api/python/yuanrong/decorator/instance_proxy.py index 42ea8fe..f277f33 100644 --- a/api/python/yr/decorator/instance_proxy.py +++ b/api/python/yuanrong/decorator/instance_proxy.py @@ -25,18 +25,18 @@ import threading import weakref import uuid from typing import List -import yr -from yr import signature -from yr.code_manager import CodeManager -from yr.generator import ObjectRefGenerator -from yr.common import constants, utils -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, function_group_enabled -from yr.libruntime_pb2 import FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime, save_real_instance_id -from yr.serialization import register_pack_hook, register_unpack_hook -from yr.accelerate.shm_broadcast import MessageQueue, STOP_EVENT +import yuanrong +from yuanrong import signature +from yuanrong.code_manager import CodeManager +from yuanrong.generator import ObjectRefGenerator +from yuanrong.common import constants, utils +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, function_group_enabled +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime, save_real_instance_id +from yuanrong.serialization import register_pack_hook, register_unpack_hook +from yuanrong.accelerate.shm_broadcast import MessageQueue, STOP_EVENT _logger = logging.getLogger(__name__) @@ -253,7 +253,7 @@ class InstanceCreator: self._code_ref is None or not global_runtime.get_runtime().is_object_existing_in_local(self._code_ref.id) ): - self._code_ref = yr.put(self.__user_class__) + self._code_ref = yuanrong.put(self.__user_class__) _logger.info("[Reference Counting] put code with id = %s, className = %s", self._code_ref.id, self.__user_class_descriptor__.class_name) # __init__ existed when user-defined @@ -601,7 +601,7 @@ class MethodProxy: raise RuntimeError(f"invalid return_nums: {return_nums}, should be an integer between 0 and 100") - def invoke(self, *args, **kwargs) -> "yr.ObjectRef": + def invoke(self, *args, **kwargs) -> "yuanrong.ObjectRef": """ Execute remote invoke to user functions. @@ -616,10 +616,10 @@ class MethodProxy: TypeError: If the parameter type is incorrect. Example: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Instance: ... sum = 0 ... @@ -630,13 +630,13 @@ class MethodProxy: ... return self.sum ... >>> ins = Instance.invoke() - >>> yr.get(ins.add.invoke(1)) + >>> yuanrong.get(ins.add.invoke(1)) >>> - >>> print(yr.get(ins.get.invoke())) + >>> print(yuanrong.get(ins.get.invoke())) >>> >>> ins.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ return self._invoke(args, kwargs) @@ -708,7 +708,7 @@ def make_decorator(invoke_options=None): def decorator(cls): if inspect.isclass(cls): return InstanceCreator.create_from_user_class(cls, invoke_options) - raise RuntimeError("@yr.instance decorator must be applied to a class") + raise RuntimeError("@yuanrong.instance decorator must be applied to a class") return decorator diff --git a/api/python/yr/device.py b/api/python/yuanrong/device.py similarity index 97% rename from api/python/yr/device.py rename to api/python/yuanrong/device.py index 67080c2..5897d50 100644 --- a/api/python/yr/device.py +++ b/api/python/yuanrong/device.py @@ -17,8 +17,8 @@ """device providing device buffer function.""" from enum import Enum from typing import List -from yr import runtime_holder -from yr.common.utils import Validator as validator +from yuanrong import runtime_holder +from yuanrong.common.utils import Validator as validator class DataType(Enum): diff --git a/api/python/yr/err_type.py b/api/python/yuanrong/err_type.py similarity index 100% rename from api/python/yr/err_type.py rename to api/python/yuanrong/err_type.py diff --git a/api/python/yr/exception.py b/api/python/yuanrong/exception.py similarity index 97% rename from api/python/yr/exception.py rename to api/python/yuanrong/exception.py index df571dc..2b4bd68 100644 --- a/api/python/yr/exception.py +++ b/api/python/yuanrong/exception.py @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""yr exception type""" +"""yuanrong exception type""" import cloudpickle -from yr.common import utils +from yuanrong.common import utils class YRError(Exception): @@ -142,7 +142,7 @@ class GetTimeoutError(YRError, TimeoutError): class YRChannelError(YRError): """Indicates that encountered a system error related - to yr.dag.channel. + to yuanrong.dag.channel. """ pass @@ -170,7 +170,7 @@ class GeneratorFinished(Exception): def deal_with_yr_error(future, err): - """deal with yr invoke error""" + """deal with yuanrong invoke error""" if isinstance(err, YRInvokeError): future.set_exception(err.origin_error()) else: diff --git a/api/python/yr/executor/__init__.py b/api/python/yuanrong/executor/__init__.py similarity index 100% rename from api/python/yr/executor/__init__.py rename to api/python/yuanrong/executor/__init__.py diff --git a/api/python/yr/executor/executor.py b/api/python/yuanrong/executor/executor.py similarity index 89% rename from api/python/yr/executor/executor.py rename to api/python/yuanrong/executor/executor.py index eff61b0..c36e9a7 100644 --- a/api/python/yr/executor/executor.py +++ b/api/python/yuanrong/executor/executor.py @@ -19,14 +19,14 @@ import threading from typing import List, Tuple -from yr import log -from yr.common.utils import get_environment_variable -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.executor.function_handler import FunctionHandler -from yr.executor.faas_executor import faas_call_handler, faas_init_handler -from yr.executor.faas_handler import FaasHandler -from yr.executor.posix_handler import PosixHandler -from yr.libruntime_pb2 import ApiType, InvokeType +from yuanrong import log +from yuanrong.common.utils import get_environment_variable +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.executor.faas_executor import faas_call_handler, faas_init_handler +from yuanrong.executor.faas_handler import FaasHandler +from yuanrong.executor.posix_handler import PosixHandler +from yuanrong.libruntime_pb2 import ApiType, InvokeType HANDLER = None _LOCK = threading.Lock() diff --git a/api/python/yr/executor/faas_executor.py b/api/python/yuanrong/executor/faas_executor.py similarity index 94% rename from api/python/yr/executor/faas_executor.py rename to api/python/yuanrong/executor/faas_executor.py index 0863774..2a6fa55 100644 --- a/api/python/yr/executor/faas_executor.py +++ b/api/python/yuanrong/executor/faas_executor.py @@ -22,17 +22,17 @@ import traceback import queue from typing import Any, List -from yr.code_manager import CodeManager -from yr.common.utils import to_json_string -from yr.err_type import ErrorInfo, ModuleCode, ErrorCode -from yr.functionsdk.utils import encode_base64, timeout +from yuanrong.code_manager import CodeManager +from yuanrong.common.utils import to_json_string +from yuanrong.err_type import ErrorInfo, ModuleCode, ErrorCode +from yuanrong.functionsdk.utils import encode_base64, timeout -from yr import log -from yr.common import constants -from yr.common.constants import META_PREFIX, METALEN -from yr.functionsdk.context import init_context, init_context_invoke, load_context_meta -from yr.functionsdk.logger_manager import UserLogManager -from yr.functionsdk.error_code import FaasErrorCode +from yuanrong import log +from yuanrong.common import constants +from yuanrong.common.constants import META_PREFIX, METALEN +from yuanrong.functionsdk.context import init_context, init_context_invoke, load_context_meta +from yuanrong.functionsdk.logger_manager import UserLogManager +from yuanrong.functionsdk.error_code import FaasErrorCode _STAGE_INIT = "init" _STAGE_INVOKE = "invoke" diff --git a/api/python/yr/executor/faas_handler.py b/api/python/yuanrong/executor/faas_handler.py similarity index 83% rename from api/python/yr/executor/faas_handler.py rename to api/python/yuanrong/executor/faas_handler.py index 9fae2a0..6eeadc7 100644 --- a/api/python/yr/executor/faas_handler.py +++ b/api/python/yuanrong/executor/faas_handler.py @@ -18,11 +18,11 @@ from typing import List -from yr import log -from yr.common.utils import err_to_str -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.executor.faas_executor import faas_shutdown_handler -from yr.executor.handler_intf import HandlerIntf +from yuanrong import log +from yuanrong.common.utils import err_to_str +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.executor.faas_executor import faas_shutdown_handler +from yuanrong.executor.handler_intf import HandlerIntf class FaasHandler(HandlerIntf): diff --git a/api/python/yr/executor/function_handler.py b/api/python/yuanrong/executor/function_handler.py similarity index 92% rename from api/python/yr/executor/function_handler.py rename to api/python/yuanrong/executor/function_handler.py index 897f896..4658dc4 100644 --- a/api/python/yr/executor/function_handler.py +++ b/api/python/yuanrong/executor/function_handler.py @@ -20,17 +20,17 @@ import traceback import inspect from typing import List, Tuple -from yr.libruntime_pb2 import InvokeType - -import yr -from yr import log -from yr.code_manager import CodeManager -from yr.common.utils import err_to_str -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.exception import YRInvokeError -from yr.executor.handler_intf import HandlerIntf -from yr.executor.instance_manager import InstanceManager -from yr.signature import recover_args +from yuanrong.libruntime_pb2 import InvokeType + +import yuanrong +from yuanrong import log +from yuanrong.code_manager import CodeManager +from yuanrong.common.utils import err_to_str +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.exception import YRInvokeError +from yuanrong.executor.handler_intf import HandlerIntf +from yuanrong.executor.instance_manager import InstanceManager +from yuanrong.signature import recover_args USER_SHUTDOWN_FUNC_NAME = "__yr_shutdown__" @@ -155,7 +155,7 @@ class FunctionHandler(HandlerIntf): return result def __get_param(self, args: List) -> Tuple[object, object]: - params = yr.serialization.Serialization().deserialize(args) + params = yuanrong.serialization.Serialization().deserialize(args) args, kwargs = recover_args(params) return args, kwargs diff --git a/api/python/yr/executor/handler_intf.py b/api/python/yuanrong/executor/handler_intf.py similarity index 97% rename from api/python/yr/executor/handler_intf.py rename to api/python/yuanrong/executor/handler_intf.py index 2c18f59..e74f510 100644 --- a/api/python/yr/executor/handler_intf.py +++ b/api/python/yuanrong/executor/handler_intf.py @@ -19,7 +19,7 @@ from abc import ABC, abstractmethod from typing import List -from yr.err_type import ErrorInfo +from yuanrong.err_type import ErrorInfo class HandlerIntf(ABC): diff --git a/api/python/yr/executor/instance_manager.py b/api/python/yuanrong/executor/instance_manager.py similarity index 97% rename from api/python/yr/executor/instance_manager.py rename to api/python/yuanrong/executor/instance_manager.py index 72d9600..0d7ce0a 100644 --- a/api/python/yr/executor/instance_manager.py +++ b/api/python/yuanrong/executor/instance_manager.py @@ -16,8 +16,8 @@ """instance manager""" -from yr.common.singleton import Singleton -from yr.object_ref import ObjectRef +from yuanrong.common.singleton import Singleton +from yuanrong.object_ref import ObjectRef @Singleton diff --git a/api/python/yr/executor/posix_handler.py b/api/python/yuanrong/executor/posix_handler.py similarity index 95% rename from api/python/yr/executor/posix_handler.py rename to api/python/yuanrong/executor/posix_handler.py index c26319e..95d9967 100644 --- a/api/python/yr/executor/posix_handler.py +++ b/api/python/yuanrong/executor/posix_handler.py @@ -18,7 +18,7 @@ from typing import List -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode class PosixHandler: diff --git a/api/python/yr/fcc.py b/api/python/yuanrong/fcc.py similarity index 80% rename from api/python/yr/fcc.py rename to api/python/yuanrong/fcc.py index 3e568e3..da65ca1 100644 --- a/api/python/yr/fcc.py +++ b/api/python/yuanrong/fcc.py @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Union, List -from yr.config import FunctionGroupOptions, FunctionGroupContext -from yr.decorator import function_proxy, instance_proxy -from yr.runtime_holder import global_runtime -import yr +from yuanrong.config import FunctionGroupOptions, FunctionGroupContext +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.runtime_holder import global_runtime +import yuanrong def create_function_group( @@ -25,7 +25,7 @@ def create_function_group( args: tuple, group_size: int, options: FunctionGroupOptions, -) -> Union[List["yr.ObjectRef"], instance_proxy.FunctionGroupHandler]: +) -> Union[List["yuanrong.ObjectRef"], instance_proxy.FunctionGroupHandler]: """ Create function group instance. @@ -53,19 +53,19 @@ def create_function_group( Raises: ValueError: If the `FunctionGroupOptions` or `group_size` parameter is incorrectly filled, this exception will be thrown. - RuntimeError: If function is not wrapped by `@yr.invoke` or `@yr.instance`, this exception will be thrown. + RuntimeError: If function is not wrapped by `@yuanrong.invoke` or `@yuanrong.instance`, this exception will be thrown. Examples: stateless function invoke example: - >>> import yr + >>> import yuanrong >>> - >>> yr.init() + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo_func(name): ... return name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -74,15 +74,15 @@ def create_function_group( ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "function_demo" - >>> objs = yr.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) - >>> rets = yr.get(objs) + >>> objs = yuanrong.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) + >>> rets = yuanrong.get(objs) >>> assert rets == [name for i in range(1, 9)] - >>> yr.finalize() + >>> yuanrong.finalize() class invoke example: - >>> import yr + >>> import yuanrong >>> - >>> @yr.instance + >>> @yuanrong.instance ... class Demo(object): ... name = "" >>> @@ -92,7 +92,7 @@ def create_function_group( >>> def return_name(self): ... return self.name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -101,13 +101,13 @@ def create_function_group( ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "class_demo" - >>> function_group_handler = yr.fcc.create_function_group(Demo, args=(name, ), group_size=8, options=opts) + >>> function_group_handler = yuanrong.fcc.create_function_group(Demo, args=(name, ), group_size=8, options=opts) >>> objs = function_group_handler.return_name.invoke() - >>> results = yr.get(objs) + >>> results = yuanrong.get(objs) >>> assert results == [name for i in range(1, 9)] >>> function_group_handler.terminate() >>> - >>> yr.finalize() + >>> yuanrong.finalize() """ bundle_size = options.scheduling_affinity_each_bundle_size if bundle_size is None or bundle_size <= 0: @@ -123,7 +123,7 @@ def create_function_group( options.timeout = -1 if options.timeout != -1 and options.timeout < 0 or options.timeout > 0x7FFFFFFF: raise ValueError(f"invalid timeout {options.timeout} in FunctionGroupOptions, expect:-1, [0, 0x7FFFFFFF]") - opts = yr.InvokeOptions() + opts = yuanrong.InvokeOptions() opts.function_group_options = options opts.cpu = opts.cpu if options.cpu is None else options.cpu opts.memory = opts.memory if options.memory is None else options.memory @@ -136,7 +136,7 @@ def create_function_group( return proxy.get_function_group_handler() if isinstance(wrapper, function_proxy.FunctionProxy): return wrapper.options(opts).set_function_group_size(group_size).invoke(*args) - raise RuntimeError("function is not wrapped by @yr.invoke or @yr.instance") + raise RuntimeError("function is not wrapped by @yuanrong.invoke or @yuanrong.instance") def get_function_group_context() -> FunctionGroupContext: @@ -153,16 +153,16 @@ def get_function_group_context() -> FunctionGroupContext: The function group context, i.e., FunctionGroupContext. Examples: - >>> import yr - >>> yr.init() + >>> import yuanrong + >>> yuanrong.init() >>> - >>> @yr.invoke + >>> @yuanrong.invoke ... def demo_func(name): - ... context = yr.fcc.get_function_group_context() + ... context = yuanrong.fcc.get_function_group_context() ... print(context) ... return name >>> - >>> opts = yr.FunctionGroupOptions( + >>> opts = yuanrong.FunctionGroupOptions( ... cpu=1000, ... memory=1000, ... resources={ @@ -171,9 +171,9 @@ def get_function_group_context() -> FunctionGroupContext: ... scheduling_affinity_each_bundle_size=2, ... ) >>> name = "function_demo" - >>> objs = yr.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) - >>> rets = yr.get(objs) + >>> objs = yuanrong.fcc.create_function_group(demo_func, args=(name,), group_size=8, options=opts) + >>> rets = yuanrong.get(objs) >>> assert rets == [name for i in range(1, 9)] - >>> yr.finalize() + >>> yuanrong.finalize() """ return global_runtime.get_runtime().get_function_group_context() diff --git a/api/python/yr/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx similarity index 100% rename from api/python/yr/fnruntime.pyx rename to api/python/yuanrong/fnruntime.pyx diff --git a/api/python/yr/functionsdk/__init__.py b/api/python/yuanrong/functionsdk/__init__.py similarity index 100% rename from api/python/yr/functionsdk/__init__.py rename to api/python/yuanrong/functionsdk/__init__.py diff --git a/api/python/yr/functionsdk/context.py b/api/python/yuanrong/functionsdk/context.py similarity index 99% rename from api/python/yr/functionsdk/context.py rename to api/python/yuanrong/functionsdk/context.py index 0f3646c..410a6d0 100644 --- a/api/python/yr/functionsdk/context.py +++ b/api/python/yuanrong/functionsdk/context.py @@ -22,9 +22,9 @@ import os import time from typing import Any, Dict -from yr import log -from yr.common import constants -from yr.functionsdk.utils import parse_json_data_to_dict, dump_data_to_json_str +from yuanrong import log +from yuanrong.common import constants +from yuanrong.functionsdk.utils import parse_json_data_to_dict, dump_data_to_json_str _RUNTIME_MAX_RESP_BODY_SIZE = 6 * 1024 * 1024 _RUNTIME_CODE_ROOT = "/opt/function/code" diff --git a/api/python/yr/functionsdk/error_code.py b/api/python/yuanrong/functionsdk/error_code.py similarity index 100% rename from api/python/yr/functionsdk/error_code.py rename to api/python/yuanrong/functionsdk/error_code.py diff --git a/api/python/yr/functionsdk/function.py b/api/python/yuanrong/functionsdk/function.py similarity index 96% rename from api/python/yr/functionsdk/function.py rename to api/python/yuanrong/functionsdk/function.py index 13df03c..d41d4c2 100644 --- a/api/python/yr/functionsdk/function.py +++ b/api/python/yuanrong/functionsdk/function.py @@ -22,14 +22,14 @@ import os import re from typing import Tuple, Union, Dict, List -from yr import log -from yr.config import InvokeOptions as YRInvokeOptions -from yr.common import constants -from yr.common.constants import META_PREFIX -from yr.libruntime_pb2 import ApiType, FunctionMeta, LanguageType -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.functionsdk.context import Context +from yuanrong import log +from yuanrong.config import InvokeOptions as YRInvokeOptions +from yuanrong.common import constants +from yuanrong.common.constants import META_PREFIX +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta, LanguageType +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.functionsdk.context import Context DEFAULT_FUNCTION_VERSION = "latest" DEFAULT_INVOKE_TIMEOUT = 900 @@ -288,7 +288,7 @@ def _check_reg_length(name: str, pattern: str, length_limit: int): def _convert_invoke_options(options: InvokeOptions, context: Context) -> YRInvokeOptions: - """convert invoke options to yr options""" + """convert invoke options to yuanrong options""" if options.concurrency == 0: options.concurrency = 100 yr_options = YRInvokeOptions() diff --git a/api/python/yr/functionsdk/logger.py b/api/python/yuanrong/functionsdk/logger.py similarity index 98% rename from api/python/yr/functionsdk/logger.py rename to api/python/yuanrong/functionsdk/logger.py index 4b750f6..8f2a586 100644 --- a/api/python/yr/functionsdk/logger.py +++ b/api/python/yuanrong/functionsdk/logger.py @@ -22,7 +22,7 @@ import logging.handlers import os import shutil -from yr.log import CustomFilter, RuntimeLogger +from yuanrong.log import CustomFilter, RuntimeLogger LOG_DEFAULT_MAX_BYTES = 50 * 1024 * 1024 LOG_DEFAULT_BACKUP_COUNT = 3 diff --git a/api/python/yr/functionsdk/logger_manager.py b/api/python/yuanrong/functionsdk/logger_manager.py similarity index 98% rename from api/python/yr/functionsdk/logger_manager.py rename to api/python/yuanrong/functionsdk/logger_manager.py index a6b8a5a..2729c9d 100644 --- a/api/python/yr/functionsdk/logger_manager.py +++ b/api/python/yuanrong/functionsdk/logger_manager.py @@ -21,8 +21,8 @@ import socket import threading from queue import Queue -from yr.common.singleton import Singleton -from yr.functionsdk import logger +from yuanrong.common.singleton import Singleton +from yuanrong.functionsdk import logger class Log: diff --git a/api/python/yr/functionsdk/utils.py b/api/python/yuanrong/functionsdk/utils.py similarity index 100% rename from api/python/yr/functionsdk/utils.py rename to api/python/yuanrong/functionsdk/utils.py diff --git a/api/python/yr/generator.py b/api/python/yuanrong/generator.py similarity index 96% rename from api/python/yr/generator.py rename to api/python/yuanrong/generator.py index 0ca6a32..1af7553 100644 --- a/api/python/yr/generator.py +++ b/api/python/yuanrong/generator.py @@ -18,10 +18,10 @@ import asyncio import logging from typing import Optional -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime -from yr.fnruntime import GeneratorEndError -from yr.exception import GeneratorFinished +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime +from yuanrong.fnruntime import GeneratorEndError +from yuanrong.exception import GeneratorFinished _logger = logging.getLogger(__name__) diff --git a/api/python/yr/group.py b/api/python/yuanrong/group.py similarity index 94% rename from api/python/yr/group.py rename to api/python/yuanrong/group.py index 921e00b..9350d1b 100644 --- a/api/python/yr/group.py +++ b/api/python/yuanrong/group.py @@ -15,8 +15,8 @@ # limitations under the License. from dataclasses import dataclass -from yr.config import GroupOptions -from yr import log, runtime_holder +from yuanrong.config import GroupOptions +from yuanrong import log, runtime_holder @dataclass diff --git a/api/python/yr/includes/__init__.pxd b/api/python/yuanrong/includes/__init__.pxd similarity index 100% rename from api/python/yr/includes/__init__.pxd rename to api/python/yuanrong/includes/__init__.pxd diff --git a/api/python/yr/includes/affinity.pxd b/api/python/yuanrong/includes/affinity.pxd similarity index 100% rename from api/python/yr/includes/affinity.pxd rename to api/python/yuanrong/includes/affinity.pxd diff --git a/api/python/yr/includes/affinity.pxi b/api/python/yuanrong/includes/affinity.pxi similarity index 100% rename from api/python/yr/includes/affinity.pxi rename to api/python/yuanrong/includes/affinity.pxi diff --git a/api/python/yr/includes/buffer.pxi b/api/python/yuanrong/includes/buffer.pxi similarity index 100% rename from api/python/yr/includes/buffer.pxi rename to api/python/yuanrong/includes/buffer.pxi diff --git a/api/python/yr/includes/libruntime.pxd b/api/python/yuanrong/includes/libruntime.pxd similarity index 99% rename from api/python/yr/includes/libruntime.pxd rename to api/python/yuanrong/includes/libruntime.pxd index 6a87ffd..7273e13 100644 --- a/api/python/yr/includes/libruntime.pxd +++ b/api/python/yuanrong/includes/libruntime.pxd @@ -24,7 +24,7 @@ from libcpp.memory cimport shared_ptr from libcpp.optional cimport optional from libcpp.unordered_set cimport unordered_set from libcpp.unordered_map cimport unordered_map -from yr.includes.affinity cimport CAffinity +from yuanrong.includes.affinity cimport CAffinity ctypedef void (*CWaitAsyncCallback) (const string & object_id, const CErrorInfo & error, void *userData) ctypedef void (*CGetAsyncCallback) (shared_ptr[CDataObject] data, const CErrorInfo & error, void *userData) diff --git a/api/python/yr/includes/libruntime.pxi b/api/python/yuanrong/includes/libruntime.pxi similarity index 100% rename from api/python/yr/includes/libruntime.pxi rename to api/python/yuanrong/includes/libruntime.pxi diff --git a/api/python/yr/includes/serialization.pxi b/api/python/yuanrong/includes/serialization.pxi similarity index 100% rename from api/python/yr/includes/serialization.pxi rename to api/python/yuanrong/includes/serialization.pxi diff --git a/api/python/yr/local_mode/__init__.py b/api/python/yuanrong/local_mode/__init__.py similarity index 100% rename from api/python/yr/local_mode/__init__.py rename to api/python/yuanrong/local_mode/__init__.py diff --git a/api/python/yr/local_mode/dependency_manager.py b/api/python/yuanrong/local_mode/dependency_manager.py similarity index 94% rename from api/python/yr/local_mode/dependency_manager.py rename to api/python/yuanrong/local_mode/dependency_manager.py index 39bdaf5..bfa83bc 100644 --- a/api/python/yr/local_mode/dependency_manager.py +++ b/api/python/yuanrong/local_mode/dependency_manager.py @@ -23,9 +23,9 @@ import logging from dataclasses import dataclass from typing import Union, List, Callable, Optional -from yr.local_mode.task_spec import TaskSpec -from yr.object_ref import ObjectRef -from yr.runtime_holder import global_runtime +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime_holder import global_runtime _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/instance.py b/api/python/yuanrong/local_mode/instance.py similarity index 100% rename from api/python/yr/local_mode/instance.py rename to api/python/yuanrong/local_mode/instance.py diff --git a/api/python/yr/local_mode/instance_manager.py b/api/python/yuanrong/local_mode/instance_manager.py similarity index 94% rename from api/python/yr/local_mode/instance_manager.py rename to api/python/yuanrong/local_mode/instance_manager.py index ba2c0f1..8ad6208 100644 --- a/api/python/yr/local_mode/instance_manager.py +++ b/api/python/yuanrong/local_mode/instance_manager.py @@ -23,16 +23,16 @@ from collections import OrderedDict, defaultdict from concurrent.futures import Future from typing import Optional, List, Tuple -from yr.common.utils import generate_task_id, generate_random_id +from yuanrong.common.utils import generate_task_id, generate_random_id -from yr.exception import YRInvokeError +from yuanrong.exception import YRInvokeError -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.scheduler import Scheduler -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.timer import Timer +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.scheduler import Scheduler +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.timer import Timer _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/local_client.py b/api/python/yuanrong/local_mode/local_client.py similarity index 92% rename from api/python/yr/local_mode/local_client.py rename to api/python/yuanrong/local_mode/local_client.py index 958fa0d..a7e32a6 100644 --- a/api/python/yr/local_mode/local_client.py +++ b/api/python/yuanrong/local_mode/local_client.py @@ -18,10 +18,10 @@ import logging import threading -from yr.common.utils import generate_random_id -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.worker import Worker +from yuanrong.common.utils import generate_random_id +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.worker import Worker _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/local_mode_runtime.py b/api/python/yuanrong/local_mode/local_mode_runtime.py similarity index 95% rename from api/python/yr/local_mode/local_mode_runtime.py rename to api/python/yuanrong/local_mode/local_mode_runtime.py index 962e042..b4af10e 100644 --- a/api/python/yr/local_mode/local_mode_runtime.py +++ b/api/python/yuanrong/local_mode/local_mode_runtime.py @@ -21,23 +21,23 @@ from abc import ABC from concurrent import futures from concurrent.futures import Future from typing import Union, Dict, List, Any, Tuple, Callable -from yr.accelerate.shm_broadcast import Handle -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.exception import YRInvokeError -from yr.stream import ProducerConfig, SubscriptionConfig -from yr.common.utils import ( +from yuanrong.accelerate.shm_broadcast import Handle +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.exception import YRInvokeError +from yuanrong.stream import ProducerConfig, SubscriptionConfig +from yuanrong.common.utils import ( generate_random_id, generate_task_id, GaugeData, UInt64CounterData, DoubleCounterData ) -from yr.fnruntime import Producer, Consumer -from yr.local_mode.local_client import LocalClient -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_manager import TaskManager -from yr.libruntime_pb2 import FunctionMeta, InvokeType -from yr.local_mode.task_spec import TaskSpec +from yuanrong.fnruntime import Producer, Consumer +from yuanrong.local_mode.local_client import LocalClient +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_manager import TaskManager +from yuanrong.libruntime_pb2 import FunctionMeta, InvokeType +from yuanrong.local_mode.task_spec import TaskSpec -from yr.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams -from yr.fnruntime import SharedBuffer +from yuanrong.runtime import Runtime, AlarmInfo, SetParam, MSetParam, CreateParam, GetParams +from yuanrong.fnruntime import SharedBuffer _logger = logging.getLogger(__name__) @@ -453,10 +453,10 @@ class LocalModeRuntime(Runtime, ABC): RuntimeError: The name of ResourceGroup is invalid. Examples: - >>> yr.remove_resource_group("rgname") + >>> yuanrong.remove_resource_group("rgname") >>> - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") - >>> yr.remove_resource_group(rg) + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> yuanrong.remove_resource_group(rg) """ raise RuntimeError("not support in local mode") diff --git a/api/python/yr/local_mode/local_object_store.py b/api/python/yuanrong/local_mode/local_object_store.py similarity index 99% rename from api/python/yr/local_mode/local_object_store.py rename to api/python/yuanrong/local_mode/local_object_store.py index 3d56aed..7343d34 100644 --- a/api/python/yr/local_mode/local_object_store.py +++ b/api/python/yuanrong/local_mode/local_object_store.py @@ -19,7 +19,7 @@ import logging import threading from typing import List -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/scheduler.py b/api/python/yuanrong/local_mode/scheduler.py similarity index 95% rename from api/python/yr/local_mode/scheduler.py rename to api/python/yuanrong/local_mode/scheduler.py index 3321221..5544e57 100644 --- a/api/python/yr/local_mode/scheduler.py +++ b/api/python/yuanrong/local_mode/scheduler.py @@ -19,8 +19,8 @@ from abc import abstractmethod, ABC from typing import Optional, Iterable, List -from yr.local_mode.instance import Instance -from yr.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.instance import Instance +from yuanrong.local_mode.task_spec import TaskSpec class Scorer(ABC): diff --git a/api/python/yr/local_mode/task_manager.py b/api/python/yuanrong/local_mode/task_manager.py similarity index 93% rename from api/python/yr/local_mode/task_manager.py rename to api/python/yuanrong/local_mode/task_manager.py index adfc712..8db2ee4 100644 --- a/api/python/yr/local_mode/task_manager.py +++ b/api/python/yuanrong/local_mode/task_manager.py @@ -24,17 +24,17 @@ from threading import RLock, Lock, BoundedSemaphore, Thread from typing import List from typing import Optional -import yr.apis -from yr.exception import CancelError +import yuanrong.apis +from yuanrong.exception import CancelError -from yr.config import InvokeOptions -from yr.config_manager import ConfigManager -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.instance_manager import InstanceManager -from yr.local_mode.scheduler import NormalScheduler, ConcurrencyScorer -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.timer import Timer +from yuanrong.config import InvokeOptions +from yuanrong.config_manager import ConfigManager +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.instance_manager import InstanceManager +from yuanrong.local_mode.scheduler import NormalScheduler, ConcurrencyScorer +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.timer import Timer class TaskState(Enum): @@ -79,8 +79,8 @@ class TaskManager: def submit_task(self, task: TaskSpec): """submit task""" - if not yr.apis.is_initialized(): - _logger.warning("Can not submit task %s before yr.init", task.task_id) + if not yuanrong.apis.is_initialized(): + _logger.warning("Can not submit task %s before yuanrong.init", task.task_id) return if task.invoke_options: invoke_options = task.invoke_options diff --git a/api/python/yr/local_mode/task_spec.py b/api/python/yuanrong/local_mode/task_spec.py similarity index 91% rename from api/python/yr/local_mode/task_spec.py rename to api/python/yuanrong/local_mode/task_spec.py index e7ada53..2f52780 100644 --- a/api/python/yr/local_mode/task_spec.py +++ b/api/python/yuanrong/local_mode/task_spec.py @@ -21,8 +21,8 @@ from concurrent.futures import Future from dataclasses import dataclass, field from typing import List, Any -from yr.config import InvokeOptions -from yr.libruntime_pb2 import FunctionMeta, InvokeType +from yuanrong.config import InvokeOptions +from yuanrong.libruntime_pb2 import FunctionMeta, InvokeType _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/timer.py b/api/python/yuanrong/local_mode/timer.py similarity index 98% rename from api/python/yr/local_mode/timer.py rename to api/python/yuanrong/local_mode/timer.py index 47f23a2..5d4d852 100644 --- a/api/python/yr/local_mode/timer.py +++ b/api/python/yuanrong/local_mode/timer.py @@ -21,7 +21,7 @@ import time from threading import Thread from typing import Callable -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton _logger = logging.getLogger(__name__) diff --git a/api/python/yr/local_mode/worker.py b/api/python/yuanrong/local_mode/worker.py similarity index 93% rename from api/python/yr/local_mode/worker.py rename to api/python/yuanrong/local_mode/worker.py index a52e2bf..4c47a0b 100644 --- a/api/python/yr/local_mode/worker.py +++ b/api/python/yuanrong/local_mode/worker.py @@ -22,14 +22,14 @@ import threading import traceback from typing import Iterable -import yr +import yuanrong -from yr import signature -from yr.exception import YRInvokeError, YRError -from yr.libruntime_pb2 import InvokeType -from yr.local_mode.local_object_store import LocalObjectStore -from yr.local_mode.task_spec import TaskSpec -from yr.object_ref import ObjectRef +from yuanrong import signature +from yuanrong.exception import YRInvokeError, YRError +from yuanrong.libruntime_pb2 import InvokeType +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.object_ref import ObjectRef _logger = logging.getLogger(__name__) @@ -135,7 +135,7 @@ def _normal_function(task: TaskSpec, *args, **kwargs): def _process_args(args_list): def func(arg): if isinstance(arg, ObjectRef): - return yr.get(arg) + return yuanrong.get(arg) return arg return list(map(func, args_list)) diff --git a/api/python/yr/log.py b/api/python/yuanrong/log.py similarity index 98% rename from api/python/yr/log.py rename to api/python/yuanrong/log.py index 0838cac..928bbe1 100644 --- a/api/python/yr/log.py +++ b/api/python/yuanrong/log.py @@ -25,12 +25,12 @@ import time from logging import Logger import logging.config -from yr.common.singleton import Singleton +from yuanrong.common.singleton import Singleton # MAX_ROW_SIZE max row size of a log _MAX_ROW_SIZE = 1024 * 1024 # python runtime log location -_BASE_LOG_NAME = "yr" +_BASE_LOG_NAME = "yuanrong" _LOG_SUFFIX = "_runtime.log" diff --git a/api/python/yr/main/__init__.py b/api/python/yuanrong/main/__init__.py similarity index 100% rename from api/python/yr/main/__init__.py rename to api/python/yuanrong/main/__init__.py diff --git a/api/python/yr/main/yr_runtime_main.py b/api/python/yuanrong/main/yr_runtime_main.py similarity index 94% rename from api/python/yr/main/yr_runtime_main.py rename to api/python/yuanrong/main/yr_runtime_main.py index df5d743..805b31e 100644 --- a/api/python/yr/main/yr_runtime_main.py +++ b/api/python/yuanrong/main/yr_runtime_main.py @@ -14,17 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""yr runtime main""" +"""yuanrong runtime main""" import argparse import json import os import sys -from yr import init, log -from yr.apis import receive_request_loop -from yr.config import Config -from yr.common.utils import try_install_uvloop +from yuanrong import init, log +from yuanrong.apis import receive_request_loop +from yuanrong.config import Config +from yuanrong.common.utils import try_install_uvloop DEFAULT_LOG_DIR = "/home/snuser/log/" _ENV_KEY_FUNCTION_LIB_PATH = "YR_FUNCTION_LIB_PATH" diff --git a/api/python/yr/metrics.py b/api/python/yuanrong/metrics.py similarity index 88% rename from api/python/yr/metrics.py rename to api/python/yuanrong/metrics.py index b651b57..3c3df2b 100644 --- a/api/python/yr/metrics.py +++ b/api/python/yuanrong/metrics.py @@ -18,10 +18,10 @@ import re from dataclasses import field from typing import Dict -from yr.config_manager import ConfigManager -from yr.runtime import AlarmInfo -from yr.runtime_holder import global_runtime -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.config_manager import ConfigManager +from yuanrong.runtime import AlarmInfo +from yuanrong.runtime_holder import global_runtime +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData _METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$') _METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') @@ -90,15 +90,15 @@ class Gauge(Metrics): ValueError: Labels are missing, or the data does not conform to Prometheus standard requirements. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) - >>> @yr.instance + >>> @yuanrong.instance ... class GaugeActor: ... def __init__(self): ... self.labels = {"key1": "value1"} - ... self.gauge = yr.Gauge( + ... self.gauge = yuanrong.Gauge( ... name="test", ... description="", ... unit="ms", @@ -116,7 +116,7 @@ class Gauge(Metrics): >>> >>> actor = GaugeActor.options(name="gauge_actor").invoke() >>> result = actor.set_value.invoke(75) - >>> print("Driver got:", yr.get(result)) + >>> print("Driver got:", yuanrong.get(result)) """ self._check_label(labels) @@ -137,15 +137,15 @@ class Gauge(Metrics): (such as reporting data types other than float). Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance ... class GaugeActor: ... def __init__(self): ... self.labels = {"key1": "value1"} - ... self.gauge = yr.Gauge( + ... self.gauge = yuanrong.Gauge( ... name="test", ... description="", ... unit="ms", @@ -165,7 +165,7 @@ class Gauge(Metrics): >>> actor = GaugeActor.options(name="gauge_actor").invoke() >>> >>> result = actor.set_value.invoke(75) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ fvalue = float(value) if ConfigManager().is_driver: @@ -210,16 +210,16 @@ class UInt64Counter(Metrics): ValueError: If the label is empty or does not meet the data type requirements. Example: - >>> import yr + >>> import yuanrong >>> - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: ... def __init__(self): ... labels = {"key1": "value1", "key2": "value2"} - ... self.data = yr.UInt64Counter( + ... self.data = yuanrong.UInt64Counter( ... name="test", ... description="", ... unit="ms", @@ -239,7 +239,7 @@ class UInt64Counter(Metrics): ... return msg >>> >>> actor1 = Actor.options(name="actor").invoke() - >>> print(yr.get(actor1.run.invoke())) + >>> print(yuanrong.get(actor1.run.invoke())) """ self._check_label(labels) @@ -259,14 +259,14 @@ class UInt64Counter(Metrics): ValueError: Invoked in the driver. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance ... class MyActor: ... def __init__(self): - ... self.data = yr.UInt64Counter( + ... self.data = yuanrong.UInt64Counter( ... "userFuncTime", ... "user function cost time", ... "ms", @@ -289,7 +289,7 @@ class UInt64Counter(Metrics): ... } >>> actor = MyActor.options(name="actor").invoke() >>> result = actor.add.invoke(5) - >>> print(yr.get(result)) + >>> print(yuanrong.get(result)) """ ivalue = int(value) if ConfigManager().is_driver: @@ -358,15 +358,15 @@ class DoubleCounter(Metrics): ValueError: If the labels are empty. Example: - >>> import yr + >>> import yuanrong >>> - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): - >>> self.data = yr.DoubleCounter( + >>> self.data = yuanrong.DoubleCounter( >>> "userFuncTime", >>> "user function cost time", >>> "ms", @@ -386,7 +386,7 @@ class DoubleCounter(Metrics): >>> return msg >>> actor1 = Actor.options(name="actor").invoke() >>> result = actor1.run.invoke() - >>> print("run result:", yr.get(result)) + >>> print("run result:", yuanrong.get(result)) """ self._check_label(labels) if len(labels) == 0: @@ -405,15 +405,15 @@ class DoubleCounter(Metrics): ValueError: Invoked in the driver. Example: - >>> import yr - >>> config = yr.Config(enable_metrics=True) - >>> yr.init(config) + >>> import yuanrong + >>> config = yuanrong.Config(enable_metrics=True) + >>> yuanrong.init(config) >>> - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): >>> try: - >>> self.data = yr.DoubleCounter( + >>> self.data = yuanrong.DoubleCounter( >>> "userFuncTime", >>> "user function cost time", >>> "ms", @@ -489,13 +489,13 @@ class Alarm(Metrics): ValueError: If alarm_name is None. Example: - >>> import yr + >>> import yuanrong >>> import time - >>> config = yr.Config(enable_metrics=True) + >>> config = yuanrong.Config(enable_metrics=True) >>> config.log_level="DEBUG":378 - >>> yr.init(config) + >>> yuanrong.init(config) - >>> @yr.instance + >>> @yuanrong.instance >>> class Actor: >>> def __init__(self): >>> self.state = 0 @@ -504,8 +504,8 @@ class Alarm(Metrics): >>> def add(self, value): >>> self.state += value >>> if self.state > 10: - >>> alarm_info = yr.AlarmInfo(alarm_name="aad") - >>> alarm = yr.Alarm(self.name, description="") + >>> alarm_info = yuanrong.AlarmInfo(alarm_name="aad") + >>> alarm = yuanrong.Alarm(self.name, description="") >>> alarm.set(alarm_info) >>> return self.state >>> @@ -514,9 +514,9 @@ class Alarm(Metrics): >>> >>> actor1 = Actor.options(name="actor1").invoke() >>> - >>> print("actor1 add 5:", yr.get(actor1.add.invoke(5))) - >>> print("actor1 add 7:", yr.get(actor1.add.invoke(7))) - >>> print("actor1 state:", yr.get(actor1.get.invoke())) + >>> print("actor1 add 5:", yuanrong.get(actor1.add.invoke(5))) + >>> print("actor1 add 7:", yuanrong.get(actor1.add.invoke(7))) + >>> print("actor1 state:", yuanrong.get(actor1.get.invoke())) """ if ConfigManager().is_driver: raise ValueError("alarm metrics set not support in driver") diff --git a/api/python/yr/object_ref.py b/api/python/yuanrong/object_ref.py similarity index 92% rename from api/python/yr/object_ref.py rename to api/python/yuanrong/object_ref.py index 83212de..017630e 100644 --- a/api/python/yr/object_ref.py +++ b/api/python/yuanrong/object_ref.py @@ -21,12 +21,12 @@ import json from concurrent.futures import Future from typing import Any, Union -from yr.exception import YRInvokeError, YRError, GeneratorFinished -from yr.err_type import ErrorInfo, ErrorCode +from yuanrong.exception import YRInvokeError, YRError, GeneratorFinished +from yuanrong.err_type import ErrorInfo, ErrorCode -import yr -from yr import log -from yr.common import constants +import yuanrong +from yuanrong import log +from yuanrong.common import constants def _set_future_helper( @@ -66,12 +66,12 @@ class ObjectRef: self._need_decre = need_decre self._exception = exception self._data = None - global_runtime = yr.runtime_holder.global_runtime.get_runtime() + global_runtime = yuanrong.runtime_holder.global_runtime.get_runtime() if need_incre and global_runtime and exception is None: global_runtime.increase_global_reference([self._id]) def __del__(self): - global_runtime = yr.runtime_holder.global_runtime.get_runtime() + global_runtime = yuanrong.runtime_holder.global_runtime.get_runtime() if self._need_decre and global_runtime: global_runtime.decrease_global_reference([self._id]) @@ -197,7 +197,7 @@ class ObjectRef: Args: callback (Callable): User callback. """ - yr.runtime_holder.global_runtime.get_runtime().set_get_callback(self.id, callback) + yuanrong.runtime_holder.global_runtime.get_runtime().set_get_callback(self.id, callback) def get(self, timeout: int = constants.DEFAULT_GET_TIMEOUT) -> Any: """This function is used to retrieve an object. @@ -217,7 +217,7 @@ class ObjectRef: if timeout <= constants.MIN_TIMEOUT_LIMIT and timeout != constants.NO_LIMIT: raise ValueError("Parameter 'timeout' should be greater than 0 or equal to -1 (no timeout)") - objects = yr.runtime_holder.global_runtime.get_runtime().get([self.id], timeout, False) + objects = yuanrong.runtime_holder.global_runtime.get_runtime().get([self.id], timeout, False) result_str = objects[0] try: diff --git a/api/python/yr/resource_group.py b/api/python/yuanrong/resource_group.py similarity index 81% rename from api/python/yr/resource_group.py rename to api/python/yuanrong/resource_group.py index 9bb12a7..555f6d5 100644 --- a/api/python/yr/resource_group.py +++ b/api/python/yuanrong/resource_group.py @@ -16,8 +16,8 @@ from dataclasses import dataclass from typing import Dict, List, Optional -from yr.common import constants -from yr.runtime_holder import global_runtime +from yuanrong.common import constants +from yuanrong.runtime_holder import global_runtime @dataclass @@ -26,7 +26,7 @@ class ResourceGroup: The handle returned after creating a ResourceGroup. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") """ def __init__( @@ -49,7 +49,7 @@ class ResourceGroup: All bundles under the current resource group.Data type is List[Dict]. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> bundles = rg.bundle_specs """ return self.bundles @@ -63,9 +63,9 @@ class ResourceGroup: Number of bundles in the current resource group. Data type is int. Examples: - >>> import yr - >>> yr.init() - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> import yuanrong + >>> yuanrong.init() + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> count = rg.bundle_count >>> print(count) """ @@ -80,9 +80,9 @@ class ResourceGroup: Name of the current resource group. Data type is str. Examples: - >>> import yr - >>> yr.init() - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> import yuanrong + >>> yuanrong.init() + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> name = rg.resource_group_name >>> print(name) """ @@ -101,7 +101,7 @@ class ResourceGroup: ValueError: Timeout is less than ``-1``. Examples: - >>> rg = yr.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") + >>> rg = yuanrong.create_resource_group([{"NPU":1},{"CPU":2000,"Memory":2000}], "rgname") >>> rg.wait(60) """ if timeout_seconds is None: diff --git a/api/python/yr/resource_group_ref.py b/api/python/yuanrong/resource_group_ref.py similarity index 93% rename from api/python/yr/resource_group_ref.py rename to api/python/yuanrong/resource_group_ref.py index 3c777a2..f20ee59 100644 --- a/api/python/yr/resource_group_ref.py +++ b/api/python/yuanrong/resource_group_ref.py @@ -16,8 +16,8 @@ """ObjectRef""" from typing import Optional -from yr.resource_group import ResourceGroup -from yr.fnruntime import write_to_cbuffer +from yuanrong.resource_group import ResourceGroup +from yuanrong.fnruntime import write_to_cbuffer class RgObjectRef: diff --git a/api/python/yr/runtime.py b/api/python/yuanrong/runtime.py similarity index 98% rename from api/python/yr/runtime.py rename to api/python/yuanrong/runtime.py index 95c11ce..8a257cb 100644 --- a/api/python/yr/runtime.py +++ b/api/python/yuanrong/runtime.py @@ -21,13 +21,13 @@ from dataclasses import dataclass, field from enum import Enum from typing import List, Tuple, Union, Any, Callable, Dict -from yr.common.types import GroupInfo -from yr.config import InvokeOptions, GroupOptions -from yr.libruntime_pb2 import FunctionMeta -from yr.fnruntime import SharedBuffer -from yr.common.utils import GaugeData, UInt64CounterData, DoubleCounterData -from yr.common import constants -from yr.accelerate.shm_broadcast import Handle +from yuanrong.common.types import GroupInfo +from yuanrong.config import InvokeOptions, GroupOptions +from yuanrong.libruntime_pb2 import FunctionMeta +from yuanrong.fnruntime import SharedBuffer +from yuanrong.common.utils import GaugeData, UInt64CounterData, DoubleCounterData +from yuanrong.common import constants +from yuanrong.accelerate.shm_broadcast import Handle class ExistenceOpt(Enum): diff --git a/api/python/yr/runtime_env.py b/api/python/yuanrong/runtime_env.py similarity index 99% rename from api/python/yr/runtime_env.py rename to api/python/yuanrong/runtime_env.py index 7b27d94..ef59b96 100644 --- a/api/python/yr/runtime_env.py +++ b/api/python/yuanrong/runtime_env.py @@ -20,7 +20,7 @@ import uuid from pathlib import Path from typing import Dict -from yr.config import InvokeOptions +from yuanrong.config import InvokeOptions WORKING_DIR_KEY = "WORKING_DIR" CONDA_PREFIX = "CONDA_PREFIX" diff --git a/api/python/yr/runtime_holder.py b/api/python/yuanrong/runtime_holder.py similarity index 86% rename from api/python/yr/runtime_holder.py rename to api/python/yuanrong/runtime_holder.py index edf4386..1f309ed 100644 --- a/api/python/yr/runtime_holder.py +++ b/api/python/yuanrong/runtime_holder.py @@ -18,10 +18,10 @@ runtime holder """ -from yr.config_manager import ConfigManager -from yr.cluster_mode_runtime import ClusterModeRuntime -from yr.local_mode.local_mode_runtime import LocalModeRuntime -from yr.runtime import Runtime +from yuanrong.config_manager import ConfigManager +from yuanrong.cluster_mode_runtime import ClusterModeRuntime +from yuanrong.local_mode.local_mode_runtime import LocalModeRuntime +from yuanrong.runtime import Runtime class RuntimeHolder: @@ -56,7 +56,7 @@ def save_real_instance_id(instance_id, need_order): def init(runtime=global_runtime) -> None: """ - init yr + init yuanrong :param runtime: RuntimeHolder :return: None """ diff --git a/api/python/yr/serialization/__init__.py b/api/python/yuanrong/serialization/__init__.py similarity index 87% rename from api/python/yr/serialization/__init__.py rename to api/python/yuanrong/serialization/__init__.py index fd9f265..4952680 100644 --- a/api/python/yr/serialization/__init__.py +++ b/api/python/yuanrong/serialization/__init__.py @@ -15,6 +15,6 @@ # limitations under the License. """serialization""" -from yr.serialization.serialization import Serialization, register_pack_hook, register_unpack_hook +from yuanrong.serialization.serialization import Serialization, register_pack_hook, register_unpack_hook __all__ = ["Serialization", "register_pack_hook", "register_unpack_hook"] diff --git a/api/python/yr/serialization/serialization.py b/api/python/yuanrong/serialization/serialization.py similarity index 93% rename from api/python/yr/serialization/serialization.py rename to api/python/yuanrong/serialization/serialization.py index 8d9ba67..ef9f7f9 100644 --- a/api/python/yr/serialization/serialization.py +++ b/api/python/yuanrong/serialization/serialization.py @@ -18,11 +18,11 @@ import threading from typing import Any, List, Union -import yr -from yr.common import constants -from yr.common.singleton import Singleton -from yr.fnruntime import SerializedObject, split_buffer, Buffer -from yr.serialization.serializers import MessagePackSerializer, PySerializer, pop_local_object_refs +import yuanrong +from yuanrong.common import constants +from yuanrong.common.singleton import Singleton +from yuanrong.fnruntime import SerializedObject, split_buffer, Buffer +from yuanrong.serialization.serializers import MessagePackSerializer, PySerializer, pop_local_object_refs @Singleton @@ -109,7 +109,7 @@ class Serialization: object_refs = pop_local_object_refs() if len(object_refs) != 0: object_ref_ids = [ref.id for ref in object_refs] - yr.runtime_holder.global_runtime.get_runtime().increase_global_reference(object_ref_ids) + yuanrong.runtime_holder.global_runtime.get_runtime().increase_global_reference(object_ref_ids) return result[0] if is_buffer else result def register_pack_hook(self, hook): diff --git a/api/python/yr/serialization/serializers.py b/api/python/yuanrong/serialization/serializers.py similarity index 96% rename from api/python/yr/serialization/serializers.py rename to api/python/yuanrong/serialization/serializers.py index 72e3021..33e512b 100644 --- a/api/python/yr/serialization/serializers.py +++ b/api/python/yuanrong/serialization/serializers.py @@ -22,17 +22,17 @@ import pickle import cloudpickle import msgpack -import yr -from yr import log -from yr.common.utils import NoGC, err_to_str -from yr.fnruntime import ( +import yuanrong +from yuanrong import log +from yuanrong.common.utils import NoGC, err_to_str +from yuanrong.fnruntime import ( Pickle5Writer, unpack_pickle5_buffers, Pickle5SerializedObject, RawSerializedObject, SerializedInterface ) -from yr.object_ref import ObjectRef +from yuanrong.object_ref import ObjectRef _EXT_TYPE_CODE = 101 _DEFAULT_PROTOCAL = 4 @@ -167,7 +167,7 @@ class PySerializer: obj = PySerializer._deserialize_to_pickle4(serialized_data) nested_refs = pop_local_object_refs() if len(nested_refs) != 0: - yr.runtime_holder.global_runtime.get_runtime().increase_global_reference([ref.id for ref in nested_refs]) + yuanrong.runtime_holder.global_runtime.get_runtime().increase_global_reference([ref.id for ref in nested_refs]) return obj @staticmethod diff --git a/api/python/yr/signature.py b/api/python/yuanrong/signature.py similarity index 100% rename from api/python/yr/signature.py rename to api/python/yuanrong/signature.py diff --git a/api/python/yr/stream.py b/api/python/yuanrong/stream.py similarity index 100% rename from api/python/yr/stream.py rename to api/python/yuanrong/stream.py diff --git a/api/python/yr/tests/BUILD.bazel b/api/python/yuanrong/tests/BUILD.bazel similarity index 100% rename from api/python/yr/tests/BUILD.bazel rename to api/python/yuanrong/tests/BUILD.bazel diff --git a/api/python/yr/tests/test_InvokeOptions.py b/api/python/yuanrong/tests/test_InvokeOptions.py similarity index 97% rename from api/python/yr/tests/test_InvokeOptions.py rename to api/python/yuanrong/tests/test_InvokeOptions.py index fc96612..b91860b 100644 --- a/api/python/yr/tests/test_InvokeOptions.py +++ b/api/python/yuanrong/tests/test_InvokeOptions.py @@ -15,16 +15,16 @@ # limitations under the License. import unittest -import yr +import yuanrong class TestInvokeOptions(unittest.TestCase): def setUp(self): - @yr.invoke + @yuanrong.invoke def add(x): return x + 1 self.add = add - self.opts = yr.InvokeOptions() + self.opts = yuanrong.InvokeOptions() def test_option_function_name(self): self.opts.name = 999 diff --git a/api/python/yr/tests/test_apis.py b/api/python/yuanrong/tests/test_apis.py similarity index 70% rename from api/python/yr/tests/test_apis.py rename to api/python/yuanrong/tests/test_apis.py index 6b0a23c..293ec23 100644 --- a/api/python/yr/tests/test_apis.py +++ b/api/python/yuanrong/tests/test_apis.py @@ -20,27 +20,27 @@ from concurrent.futures import Future import cloudpickle import pytest -import yr -from yr import exception -from yr import fcc -from yr.config_manager import ConfigManager -from yr.config import FunctionGroupOptions -from yr.decorator import function_proxy, instance_proxy -from yr.runtime import AlarmInfo -from yr.object_ref import ObjectRef -from yr.config import InvokeOptions - - -@yr.invoke(return_nums=0) +import yuanrong +from yuanrong import exception +from yuanrong import fcc +from yuanrong.config_manager import ConfigManager +from yuanrong.config import FunctionGroupOptions +from yuanrong.decorator import function_proxy, instance_proxy +from yuanrong.runtime import AlarmInfo +from yuanrong.object_ref import ObjectRef +from yuanrong.config import InvokeOptions + + +@yuanrong.invoke(return_nums=0) def get(): """get""" return 1 -@yr.instance +@yuanrong.instance class Counter: """Counter""" - @yr.method(return_nums=0) + @yuanrong.method(return_nums=0) def get(self): """get""" return 1 @@ -51,15 +51,15 @@ class TestApi(unittest.TestCase): pass def test_yr_init_failed_when_input_invalid_address(self): - conf = yr.Config() - conf.function_id = "sn:cn:yrk:12345678901234561234567890123456:function:0-yr-test-config-init:$latest" + conf = yuanrong.Config() + conf.function_id = "sn:cn:yrk:12345678901234561234567890123456:function:0-yuanrong-test-config-init:$latest" conf.server_address = "127.0.0.1:11111" conf.in_cluster = False with self.assertRaises(ValueError): - yr.init(conf) + yuanrong.init(conf) - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_wait_when_input_list_return_in_order(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.wait.return_value = (["3", "2", "1"], []) @@ -67,12 +67,12 @@ class TestApi(unittest.TestCase): mock_runtime.decrease_global_reference.return_value = None get_runtime.return_value = mock_runtime is_initialized.return_value = True - refs = [yr.object_ref.ObjectRef("1"), yr.object_ref.ObjectRef("2"), yr.object_ref.ObjectRef("3")] - ready_refs, _ = yr.wait(refs) + refs = [yuanrong.object_ref.ObjectRef("1"), yuanrong.object_ref.ObjectRef("2"), yuanrong.object_ref.ObjectRef("3")] + ready_refs, _ = yuanrong.wait(refs) assert ready_refs == refs - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_invoke_when_return_nums_is_0(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.invoke_by_name.return_value = ["1"] @@ -90,130 +90,130 @@ class TestApi(unittest.TestCase): assert c.get.invoke() is None def test_yr_init_failed_when_input_invaild_function_id(self): - conf = yr.Config() + conf = yuanrong.Config() conf.function_id = "111" conf.in_cluster = False with pytest.raises(ValueError): - yr.init(conf) + yuanrong.init(conf) def test_affinity(self): """ Test the init method of Affinity class. """ - affinity_kind = yr.AffinityKind.INSTANCE - affinity_type = yr.AffinityType.PREFERRED + affinity_kind = yuanrong.AffinityKind.INSTANCE + affinity_type = yuanrong.AffinityType.PREFERRED label_operators = [ - yr.LabelOperator(yr.OperatorType.LABEL_IN, "key", ["value1", "value2"]) + yuanrong.LabelOperator(yuanrong.OperatorType.LABEL_IN, "key", ["value1", "value2"]) ] - affinity = yr.Affinity(affinity_kind, affinity_type, label_operators) + affinity = yuanrong.Affinity(affinity_kind, affinity_type, label_operators) assert affinity_kind == affinity.affinity_kind assert affinity_type == affinity.affinity_type assert label_operators == affinity.label_operators - affinity_scope = yr.AffinityScope.NODE - affinity2 = yr.Affinity(affinity_kind, affinity_type, label_operators, affinity_scope) + affinity_scope = yuanrong.AffinityScope.NODE + affinity2 = yuanrong.Affinity(affinity_kind, affinity_type, label_operators, affinity_scope) assert affinity_scope == affinity2.affinity_scope - @patch("yr.apis.is_initialized") + @patch("yuanrong.apis.is_initialized") def test_cancel_with_invalid_value(self, is_initialized): is_initialized.return_value = True with pytest.raises(TypeError) as e: - yr.cancel("aaa") + yuanrong.cancel("aaa") print(e) assert e.value.__str__() == "obj_refs type error, actual: [], element expect: " with pytest.raises(TypeError) as e: - yr.cancel(["aaa"]) + yuanrong.cancel(["aaa"]) assert e.value.__str__() == "obj_refs type error, actual: [], element expect: " def test_double_counter(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - d = yr.DoubleCounter(name="test", description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name="test", description='', unit="ms", labels=labels) d.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: d.set(100) assert e.value.__str__() == "double counter metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - d = yr.DoubleCounter(name=name, description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name=name, description='', unit="ms", labels=labels) d.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - d = yr.DoubleCounter(name="test", description='', unit="ms", labels=labels) + d = yuanrong.DoubleCounter(name="test", description='', unit="ms", labels=labels) d.set("abc") assert e.value.__str__() == "could not convert string to float: 'abc'" def test_uint64_counter(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - u = yr.UInt64Counter(name="test", description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name="test", description='', unit="ms", labels=labels) u.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: u.set(100) assert e.value.__str__() == "uint64 counter metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - u = yr.UInt64Counter(name=name, description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name=name, description='', unit="ms", labels=labels) u.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - u = yr.UInt64Counter(name="test", description='', unit="ms", labels=labels) + u = yuanrong.UInt64Counter(name="test", description='', unit="ms", labels=labels) u.set("abc") assert e.value.__str__() == "invalid literal for int() with base 10: 'abc'" def test_gauge(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) labels = {"key1": "value1", "key2": "value2"} - g = yr.Gauge(name="test", description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name="test", description='', unit="ms", labels=labels) g.add_labels({"key3": "value3"}) with pytest.raises(ValueError) as e: g.set(100) assert e.value.__str__() == "gauge metrics report not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - g = yr.Gauge(name=name, description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name=name, description='', unit="ms", labels=labels) g.set(100) assert e.value.__str__() == "invalid metric name: *test" with pytest.raises(ValueError) as e: - g = yr.Gauge(name="test", description='', unit="ms", labels=labels) + g = yuanrong.Gauge(name="test", description='', unit="ms", labels=labels) g.set("abc") assert e.value.__str__() == "could not convert string to float: 'abc'" def test_alarm(self): with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=True)) + yuanrong.init(yuanrong.Config(is_driver=True)) alarm_info = AlarmInfo() - a = yr.Alarm(name="test", description='') + a = yuanrong.Alarm(name="test", description='') with pytest.raises(ValueError) as e: a.set(alarm_info) assert e.value.__str__() == "alarm metrics set not support in driver" with self.assertRaises(ValueError): - yr.init(yr.Config(is_driver=False)) + yuanrong.init(yuanrong.Config(is_driver=False)) with pytest.raises(ValueError) as e: name = "*test" - a = yr.Alarm(name=name, description='') + a = yuanrong.Alarm(name=name, description='') assert e.value.__str__() == "invalid metric name: *test" def test_serialize_instance_ok(self): - @yr.instance + @yuanrong.instance class Counter1: pass @@ -222,25 +222,25 @@ class TestApi(unittest.TestCase): assert type(b) == type(Counter1) assert type(b.__user_class__) == type(Counter1.__user_class__) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_finalize(self, get_runtime): mock_runtime = Mock() mock_runtime.finalize.return_value = None mock_runtime.receive_request_loop.return_value = None mock_runtime.exit().return_value = None get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - self.assertTrue(yr.apis.is_initialized()) - yr.finalize() - self.assertFalse(yr.apis.is_initialized()) - yr.apis.set_initialized() - yr.exit() - yr.finalize() - yr.apis.receive_request_loop() - self.assertFalse(yr.apis.is_initialized()) - - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + yuanrong.apis.set_initialized() + self.assertTrue(yuanrong.apis.is_initialized()) + yuanrong.finalize() + self.assertFalse(yuanrong.apis.is_initialized()) + yuanrong.apis.set_initialized() + yuanrong.exit() + yuanrong.finalize() + yuanrong.apis.receive_request_loop() + self.assertFalse(yuanrong.apis.is_initialized()) + + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_get_put_wait(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.get.return_value = [1, 2] @@ -249,55 +249,55 @@ class TestApi(unittest.TestCase): is_initialized.return_value = True v = ObjectRef("test") with self.assertRaises(TypeError): - yr.put(v) + yuanrong.put(v) with self.assertRaises(ValueError): - yr.get(v, -2, True) - self.assertFalse(yr.get([])) + yuanrong.get(v, -2, True) + self.assertFalse(yuanrong.get([])) - res = yr.get([v, v]) + res = yuanrong.get([v, v]) self.assertEqual(len(res), 2, len(res)) with self.assertRaises(ValueError): - yr.wait([v, v], 2) + yuanrong.wait([v, v], 2) with self.assertRaises(ValueError): - yr.wait([v], -1) + yuanrong.wait([v], -1) with self.assertRaises(TypeError): - yr.wait([v], "") + yuanrong.wait([v], "") with self.assertRaises(TypeError): - yr.wait([v], 1, "") + yuanrong.wait([v], 1, "") with self.assertRaises(ValueError): - yr.wait([v], 1, -2) + yuanrong.wait([v], 1, -2) with self.assertRaises(ValueError): - yr.wait([v], 1) + yuanrong.wait([v], 1) def test_instance(self): with self.assertRaises(RuntimeError): - @yr.instance(invoke_options=InvokeOptions()) + @yuanrong.instance(invoke_options=InvokeOptions()) def hello(): return "" hello() with self.assertRaises(ValueError): - @yr.method() + @yuanrong.method() def hi(): return "" hi() with self.assertRaises(TypeError): - @yr.method(return_nums="") + @yuanrong.method(return_nums="") def hi(): return "" hi() - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_stream(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.create_stream_producer.return_value = "producer" @@ -311,25 +311,25 @@ class TestApi(unittest.TestCase): get_runtime.return_value = mock_runtime is_initialized.return_value = True - self.assertEqual(yr.create_stream_producer("", None), "producer") + self.assertEqual(yuanrong.create_stream_producer("", None), "producer") - self.assertEqual(yr.create_stream_consumer("", None), "consummer") - self.assertEqual(yr.query_global_producers_num(""), 10) - self.assertEqual(yr.query_global_consumers_num(""), 10) + self.assertEqual(yuanrong.create_stream_consumer("", None), "consummer") + self.assertEqual(yuanrong.query_global_producers_num(""), 10) + self.assertEqual(yuanrong.query_global_consumers_num(""), 10) with self.assertRaises(RuntimeError): - yr.delete_stream("") + yuanrong.delete_stream("") with self.assertRaises(RuntimeError): - yr.kv_write("key", b"abc") + yuanrong.kv_write("key", b"abc") - self.assertEqual(yr.kv_read(""), "value") + self.assertEqual(yuanrong.kv_read(""), "value") with self.assertRaises(RuntimeError): - yr.kv_del("key") + yuanrong.kv_del("key") - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_state(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.save_state.side_effect = RuntimeError("mock exception") @@ -339,14 +339,14 @@ class TestApi(unittest.TestCase): with self.assertRaises(RuntimeError): ConfigManager().local_mode = True - yr.save_state() + yuanrong.save_state() with self.assertRaises(RuntimeError): ConfigManager().local_mode = False - yr.save_state() + yuanrong.save_state() - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_save_and_load_state(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.save_state.return_value = None @@ -356,35 +356,35 @@ class TestApi(unittest.TestCase): ConfigManager()._ConfigManager__in_cluster = True ConfigManager()._ConfigManager__is_driver = False ConfigManager().local_mode = False - yr.save_state() - self.assertEqual(yr.load_state(), None) + yuanrong.save_state() + self.assertEqual(yuanrong.load_state(), None) - @patch("yr.decorator.instance_proxy.get_instance_by_name") + @patch("yuanrong.decorator.instance_proxy.get_instance_by_name") def test_get_instance(self, get_instance_by_name): get_instance_by_name.side_effect = RuntimeError("mock exception") with self.assertRaises(TypeError): - yr.get_instance(1) + yuanrong.get_instance(1) with self.assertRaises(TypeError): - yr.get_instance("instance1", 1, 1) + yuanrong.get_instance("instance1", 1, 1) with self.assertRaises(TypeError): - yr.get_instance("instance1", "namespace", -2) + yuanrong.get_instance("instance1", "namespace", -2) with self.assertRaises(Exception): - yr.get_instance("instance1", "namespace", 1) + yuanrong.get_instance("instance1", "namespace", 1) def tets_resources(self): with self.assertRaises(RuntimeError): ConfigManager().local_mode = True - yr.resources() + yuanrong.resources() - @patch("yr.decorator.instance_proxy.make_cpp_instance_creator") + @patch("yuanrong.decorator.instance_proxy.make_cpp_instance_creator") def test_class_cross_instance(self, make_cpp_instance_creator): make_cpp_instance_creator.return_value = "" - urn = "sn:cn:yrk:12345678901234561234567890123456:function:0-yr-test-config-init:$latest" - cpp_class = yr.apis.cpp_instance_class( + urn = "sn:cn:yrk:12345678901234561234567890123456:function:0-yuanrong-test-config-init:$latest" + cpp_class = yuanrong.apis.cpp_instance_class( "class", "factory", urn) with self.assertRaises(Exception): @@ -397,21 +397,21 @@ class TestApi(unittest.TestCase): self.assertEqual(cpp_class.get_factory_name(), "factory") self.assertTrue("test" in cpp_class.get_function_key()) - cp = yr.apis.cpp_function("class", urn) + cp = yuanrong.apis.cpp_function("class", urn) self.assertEqual(cp.cross_language_info.function_name, "class", cp.cross_language_info) with self.assertRaises(AttributeError): - yr.apis.go_function("class", urn) + yuanrong.apis.go_function("class", urn) - jp = yr.apis.java_function("class", "factory", urn) + jp = yuanrong.apis.java_function("class", "factory", urn) self.assertEqual(jp.cross_language_info.function_name, "factory", jp.cross_language_info) - cp = yr.apis.cpp_instance_class_new( + cp = yuanrong.apis.cpp_instance_class_new( "class", "factory", urn) self.assertTrue(cp) - @patch.object(yr.decorator.instance_proxy.InstanceCreator, "options") - @patch.object(yr.decorator.function_proxy.FunctionProxy, "options") + @patch.object(yuanrong.decorator.instance_proxy.InstanceCreator, "options") + @patch.object(yuanrong.decorator.function_proxy.FunctionProxy, "options") def test_create_function_group(self, mock_function_proxy_options, mock_instance_proxy_options): opt = FunctionGroupOptions() with self.assertRaises(ValueError): @@ -462,8 +462,8 @@ class TestApi(unittest.TestCase): res = fcc.create_function_group(fp, (1, 2), 10, opt) self.assertEqual(res, "function", res) - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.apis.is_initialized") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.apis.is_initialized") def test_resource_group(self, is_initialized, get_runtime): mock_runtime = Mock() mock_runtime.create_resource_group.return_value = None @@ -471,20 +471,20 @@ class TestApi(unittest.TestCase): mock_runtime.wait_resource_group.return_value = None get_runtime.return_value = mock_runtime is_initialized.return_value = True - rg = yr.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], "rgname") + rg = yuanrong.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], "rgname") self.assertTrue(rg) rg.wait() bundles = rg.bundle_specs assert bundles == [{"NPU": 1}, {"CPU": 2000, "Memory": 2000}] count = rg.bundle_count assert count == 2 - yr.remove_resource_group("rgname") + yuanrong.remove_resource_group("rgname") with self.assertRaises(TypeError): - rg = yr.create_resource_group(None, "rgname") + rg = yuanrong.create_resource_group(None, "rgname") with self.assertRaises(ValueError): - rg = yr.create_resource_group([], "rgname") + rg = yuanrong.create_resource_group([], "rgname") with self.assertRaises(TypeError): - rg = yr.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], []) + rg = yuanrong.create_resource_group([{"NPU": 1}, {"CPU": 2000, "Memory": 2000}], []) class TestException(unittest.TestCase): diff --git a/api/python/yr/tests/test_apis_get.py b/api/python/yuanrong/tests/test_apis_get.py similarity index 81% rename from api/python/yr/tests/test_apis_get.py rename to api/python/yuanrong/tests/test_apis_get.py index 03a61b7..bcabb74 100644 --- a/api/python/yr/tests/test_apis_get.py +++ b/api/python/yuanrong/tests/test_apis_get.py @@ -15,21 +15,21 @@ # limitations under the License. import unittest -import yr +import yuanrong from unittest.mock import patch, Mock -from yr.object_ref import ObjectRef +from yuanrong.object_ref import ObjectRef class TestGet(unittest.TestCase): - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_get_invalid_timeout(self, mock_get_runtime): - obj_ref = yr.object_ref.ObjectRef(123) + obj_ref = yuanrong.object_ref.ObjectRef(123) time = -10 mock_get_runtime =Mock() mock_get_runtime.get.return_value="Parameter 'timeout' should be greater than 0 or equal to -1 (no timeout)" mock_get_runtime.return_value=mock_get_runtime - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.apis.get(obj_ref,time) + yuanrong.apis.get(obj_ref,time) if __name__ == '__main__': diff --git a/api/python/yr/tests/test_apis_put.py b/api/python/yuanrong/tests/test_apis_put.py similarity index 68% rename from api/python/yr/tests/test_apis_put.py rename to api/python/yuanrong/tests/test_apis_put.py index 6be6cca..b17d97f 100644 --- a/api/python/yr/tests/test_apis_put.py +++ b/api/python/yuanrong/tests/test_apis_put.py @@ -15,89 +15,89 @@ # limitations under the License. import unittest -import yr -from yr.object_ref import ObjectRef +import yuanrong +from yuanrong.object_ref import ObjectRef from unittest.mock import patch, Mock class TestPut(unittest.TestCase): - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_memoryview(self, mock_get_runtime): obj_refs = memoryview(bytearray(10 * 1024 * 1024)) mock_runtime = Mock() mock_runtime.put.return_value = 1 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_bytes(self, mock_get_runtime): obj_refs = bytes(10 * 1024 * 1024) mock_runtime = Mock() mock_runtime.put.return_value = 10 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_bytearray(self, mock_get_runtime): obj_refs = bytearray(10 * 1024 * 1024) mock_runtime = Mock() mock_runtime.put.return_value = 1 mock_get_runtime.return_value = mock_runtime - yr.apis.set_initialized() - result = yr.apis.put(obj_refs) + yuanrong.apis.set_initialized() + result = yuanrong.apis.put(obj_refs) self.assertIsInstance(result, ObjectRef) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_with_object_ref(self, mock_rt): mock_rt.return_value.put.side_effect = TypeError obj = ObjectRef(1) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(TypeError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_fail(self, mock_rt): mock_rt.return_value.put.side_effect = RuntimeError("mock error") with self.assertRaises(RuntimeError): - yr.put(1) + yuanrong.put(1) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_null_ptr(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError("value is None or has zero length") obj = None - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_bytes(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError obj = bytes(0) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_bytearray(self,mock_rt): mock_rt.return_value.put.side_effect = ValueError obj = bytearray(0) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_put_len_zero_memoryview(self, mock_rt): mock_rt.return_value.put.side_effect = ValueError o = bytes(0) obj = memoryview(o) - yr.apis.set_initialized() + yuanrong.apis.set_initialized() with self.assertRaises(ValueError): - yr.put(obj) + yuanrong.put(obj) diff --git a/api/python/yr/tests/test_cluster_mode_runtime.py b/api/python/yuanrong/tests/test_cluster_mode_runtime.py similarity index 94% rename from api/python/yr/tests/test_cluster_mode_runtime.py rename to api/python/yuanrong/tests/test_cluster_mode_runtime.py index ce6c63d..ca764a3 100644 --- a/api/python/yr/tests/test_cluster_mode_runtime.py +++ b/api/python/yuanrong/tests/test_cluster_mode_runtime.py @@ -16,13 +16,13 @@ import unittest from unittest.mock import Mock -import yr -from yr.config_manager import ConfigManager -from yr.err_type import ErrorCode, ErrorInfo, ModuleCode -from yr.serialization import Serialization -from yr.libruntime_pb2 import ApiType, FunctionMeta -from yr.object_ref import ObjectRef -from yr.runtime import CreateParam +import yuanrong +from yuanrong.config_manager import ConfigManager +from yuanrong.err_type import ErrorCode, ErrorInfo, ModuleCode +from yuanrong.serialization import Serialization +from yuanrong.libruntime_pb2 import ApiType, FunctionMeta +from yuanrong.object_ref import ObjectRef +from yuanrong.runtime import CreateParam class TestClusterModeRuntime(unittest.TestCase): @@ -30,7 +30,7 @@ class TestClusterModeRuntime(unittest.TestCase): def setUp(self): ConfigManager().rt_server_address = "127.0.0.1:1122" - self.runtime = yr.cluster_mode_runtime.ClusterModeRuntime() + self.runtime = yuanrong.cluster_mode_runtime.ClusterModeRuntime() self.runtime.set_initialized() def mock_get_async(obj_id, callback_wrapper): @@ -128,20 +128,20 @@ class TestClusterModeRuntime(unittest.TestCase): def test_stream(self): with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.max_stream_size = -1 self.runtime.create_stream_producer("stream", cfg) with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.retain_for_num_consumers = -1 self.runtime.create_stream_producer("stream", cfg) with self.assertRaises(RuntimeError): - cfg = yr.ProducerConfig() + cfg = yuanrong.ProducerConfig() cfg.reserve_size = -1 self.runtime.create_stream_producer("stream", cfg) - self.assertEqual(self.runtime.create_stream_producer("", yr.ProducerConfig()), "producer") - self.assertEqual(self.runtime.create_stream_consumer("", yr.ProducerConfig()), "consumer") + self.assertEqual(self.runtime.create_stream_producer("", yuanrong.ProducerConfig()), "producer") + self.assertEqual(self.runtime.create_stream_consumer("", yuanrong.ProducerConfig()), "consumer") self.assertEqual(self.runtime.query_global_producers_num(""), 10) self.assertEqual(self.runtime.query_global_consumers_num(""), 10) diff --git a/api/python/yr/tests/test_code_manager.py b/api/python/yuanrong/tests/test_code_manager.py similarity index 93% rename from api/python/yr/tests/test_code_manager.py rename to api/python/yuanrong/tests/test_code_manager.py index 82b8e03..c7cef40 100644 --- a/api/python/yr/tests/test_code_manager.py +++ b/api/python/yuanrong/tests/test_code_manager.py @@ -19,9 +19,9 @@ import sys from unittest import mock, TestCase, main -from yr.code_manager import CodeManager -from yr.err_type import ErrorCode -from yr.libruntime_pb2 import FunctionMeta +from yuanrong.code_manager import CodeManager +from yuanrong.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta logger = logging.getLogger(__name__) @@ -41,7 +41,7 @@ class TestCodeManager(TestCase): self.cm.load_functions([path]) mock_sys_path.insert.assert_called_once_with(0, path) - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_functions_when_input_invalid_faas_entry(self, mock_logger): mock_logger.return_value = logger self.cm.custom_handler = "/tmp" @@ -49,14 +49,14 @@ class TestCodeManager(TestCase): assert err.error_code == ErrorCode.ERR_USER_CODE_LOAD @mock.patch.object(CodeManager(), 'load_code_from_local') - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_functions_when_user_code_syntax_err(self, mock_logger, mock_load_code_from_local): mock_logger.return_value = logger mock_load_code_from_local.side_effect = SyntaxError("a syntax error in user code") err = CodeManager().load_functions(["test.init", "test.handler"]) assert err.error_code == ErrorCode.ERR_USER_CODE_LOAD - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_entry_load(self, mock_logger): mock_logger.return_value = logger self.assertFalse(self.cm.get_code_path("none")) @@ -102,7 +102,7 @@ class TestCodeManager(TestCase): @mock.patch("os.path.exists") @mock.patch("importlib.util.spec_from_file_location") @mock.patch("importlib.util.module_from_spec") - @mock.patch("yr.log.get_logger") + @mock.patch("yuanrong.log.get_logger") def test_load_module(self, mock_logger, mock_module_from_spec, mock_spec_from_file_location, mock_exists): mock_logger.return_value = logger mock_exists.return_value = True diff --git a/api/python/yr/tests/test_common.py b/api/python/yuanrong/tests/test_common.py similarity index 99% rename from api/python/yr/tests/test_common.py rename to api/python/yuanrong/tests/test_common.py index 938b181..a143fb3 100644 --- a/api/python/yr/tests/test_common.py +++ b/api/python/yuanrong/tests/test_common.py @@ -18,7 +18,7 @@ import logging import json from unittest import TestCase, main -from yr.common import utils +from yuanrong.common import utils logger = logging.getLogger(__name__) diff --git a/api/python/yr/tests/test_decorator.py b/api/python/yuanrong/tests/test_decorator.py similarity index 92% rename from api/python/yr/tests/test_decorator.py rename to api/python/yuanrong/tests/test_decorator.py index a702fec..408e373 100644 --- a/api/python/yr/tests/test_decorator.py +++ b/api/python/yuanrong/tests/test_decorator.py @@ -18,11 +18,11 @@ import logging from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.decorator import instance_proxy, function_proxy -from yr.object_ref import ObjectRef -from yr.config import InvokeOptions -from yr.common.utils import CrossLanguageInfo -from yr.libruntime_pb2 import LanguageType, FunctionMeta +from yuanrong.decorator import instance_proxy, function_proxy +from yuanrong.object_ref import ObjectRef +from yuanrong.config import InvokeOptions +from yuanrong.common.utils import CrossLanguageInfo +from yuanrong.libruntime_pb2 import LanguageType, FunctionMeta logger = logging.getLogger(__name__) @@ -30,8 +30,8 @@ logger = logging.getLogger(__name__) class TestDecorator(TestCase): - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") def test_instance_proxy(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() @@ -116,8 +116,8 @@ class TestDecorator(TestCase): decorator = instance_proxy.make_decorator() decorator("test") - @patch("yr.runtime_holder.global_runtime.get_runtime") - @patch("yr.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") def test_function_proxy(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() diff --git a/api/python/yr/tests/test_executor.py b/api/python/yuanrong/tests/test_executor.py similarity index 82% rename from api/python/yr/tests/test_executor.py rename to api/python/yuanrong/tests/test_executor.py index 3fcfa4c..26cf65f 100644 --- a/api/python/yr/tests/test_executor.py +++ b/api/python/yuanrong/tests/test_executor.py @@ -19,20 +19,20 @@ import os from unittest import TestCase, main from unittest.mock import Mock, patch -import yr -from yr.executor.posix_handler import PosixHandler -from yr.executor.faas_handler import FaasHandler -from yr.executor.function_handler import FunctionHandler -from yr.executor.executor import INIT_HANDLER, Executor -import yr.executor.faas_executor as faas -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +import yuanrong +from yuanrong.executor.posix_handler import PosixHandler +from yuanrong.executor.faas_handler import FaasHandler +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.executor.executor import INIT_HANDLER, Executor +import yuanrong.executor.faas_executor as faas +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType logger = logging.getLogger(__name__) class TestExecutor(TestCase): def setUp(self) -> None: - self.runtime = yr.cluster_mode_runtime.ClusterModeRuntime() + self.runtime = yuanrong.cluster_mode_runtime.ClusterModeRuntime() mock_fnruntime = Mock() mock_fnruntime.get.return_value = [b"data1", b"data2"] mock_fnruntime.config.libruntimeOptions.functionExecuteCallback = Mock() @@ -53,25 +53,25 @@ class TestExecutor(TestCase): isAsync=False) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_load_excutor(self, mock_logger): mock_logger.return_value = logger os.environ[INIT_HANDLER] = "yrlib_handler.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, FunctionHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") os.environ[INIT_HANDLER] = "faas_executor.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, FaasHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") os.environ[INIT_HANDLER] = "posix.init" Executor.load_handler() - from yr.executor.executor import HANDLER + from yuanrong.executor.executor import HANDLER self.assertTrue(isinstance(HANDLER, PosixHandler), f"Failed to load executor, HANDLER type is {type(HANDLER)}") - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_executor(self, mock_logger): mock_logger.return_value = logger e = Executor(self.function_meta, [], InvokeType.CreateInstanceStateless, 1, None, False) diff --git a/api/python/yr/tests/test_faas_handler.py b/api/python/yuanrong/tests/test_faas_handler.py similarity index 89% rename from api/python/yr/tests/test_faas_handler.py rename to api/python/yuanrong/tests/test_faas_handler.py index aa58e8a..d15630a 100644 --- a/api/python/yr/tests/test_faas_handler.py +++ b/api/python/yuanrong/tests/test_faas_handler.py @@ -18,20 +18,20 @@ import logging import json from unittest import TestCase, main from unittest.mock import Mock, patch -import yr.executor.faas_executor as faas -from yr.code_manager import CodeManager +import yuanrong.executor.faas_executor as faas +from yuanrong.code_manager import CodeManager -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType -from yr.functionsdk.context import load_context_meta -from yr.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +from yuanrong.functionsdk.context import load_context_meta +from yuanrong.err_type import ErrorCode logger = logging.getLogger(__name__) class TestFaasExecutor(TestCase): - @patch("yr.log.get_logger") - @patch("yr.executor.faas_executor.parse_faas_param") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.executor.faas_executor.parse_faas_param") @patch.object(CodeManager(), 'get_code_path') @patch.object(CodeManager(), 'load') def test_parse_faas_param(self, mock_load, mock_get_code_path, parse_faas_param, mock_logger): @@ -74,9 +74,9 @@ class TestFaasExecutor(TestCase): self.assertTrue("faas init request args json decode error" in str(e), str(e)) parse_faas_param.reset_mock() - @patch("yr.log.get_logger") - @patch("yr.executor.faas_executor.parse_faas_param") - @patch("yr.executor.faas_executor.get_trace_id_from_params") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.executor.faas_executor.parse_faas_param") + @patch("yuanrong.executor.faas_executor.get_trace_id_from_params") @patch.object(CodeManager(), 'load') def test_faas_call_handler(self, mock_load, get_trace_id_from_params, mock_parse_faas_param, mock_logger): mock_logger.return_value = logger @@ -117,7 +117,7 @@ class TestFaasExecutor(TestCase): res = faas.faas_call_handler(["arg0", "arg1"]) self.assertTrue("failed to convert the result to a JSON string" in res, res) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load') def test_faas_shutdown_handler(self, mock_load, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_fcc.py b/api/python/yuanrong/tests/test_fcc.py similarity index 87% rename from api/python/yr/tests/test_fcc.py rename to api/python/yuanrong/tests/test_fcc.py index fe5e2ef..90f712b 100644 --- a/api/python/yr/tests/test_fcc.py +++ b/api/python/yuanrong/tests/test_fcc.py @@ -20,15 +20,15 @@ import logging import time import asyncio from dataclasses import asdict -from yr.decorator.instance_proxy import FunctionGroupHandler +from yuanrong.decorator.instance_proxy import FunctionGroupHandler from unittest import TestCase, main from unittest.mock import patch, Mock, AsyncMock -from yr.fnruntime import SharedBuffer -from yr.accelerate.shm_broadcast import Handle -from yr.accelerate.executor import Worker -from yr.executor.instance_manager import InstanceManager -from yr.accelerate.shm_broadcast import STOP_EVENT, MessageQueue -import yr +from yuanrong.fnruntime import SharedBuffer +from yuanrong.accelerate.shm_broadcast import Handle +from yuanrong.accelerate.executor import Worker +from yuanrong.executor.instance_manager import InstanceManager +from yuanrong.accelerate.shm_broadcast import STOP_EVENT, MessageQueue +import yuanrong import threading logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) @@ -63,7 +63,7 @@ class TestFcc(unittest.TestCase): def setUp(self) -> None: pass - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_accelerate(self, get_runtime): data = bytearray(10 * 1024 * 1024) shared_buffer = SharedBuffer() @@ -84,7 +84,7 @@ class TestFcc(unittest.TestCase): self.assertIsNone(handler.terminate()) def test_worker_sync(self): - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger InstanceManager().instance = new_instance mock_queue = Mock() mock_queue.dequeue.return_value = ("obj", "get", (1, 2), {}) @@ -103,7 +103,7 @@ class TestFcc(unittest.TestCase): self.assertIsNone(worker.worker_busy_loop_sync()) def test_worker_async(self): - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger mock_queue = AsyncMock() InstanceManager().instance = new_instance mock_queue.dequeue_async.return_value = ("obj", "get", (1, 2), {}) @@ -121,10 +121,10 @@ class TestFcc(unittest.TestCase): thread.start() self.assertIsNone(asyncio.run(worker.worker_busy_loop_async())) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_message_queue_sync(self, get_runtime): STOP_EVENT.clear() - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger logger.info("==========================") data = bytearray((10 * 1024 * 1024 + 2) * 10) shared_buffer = MockSharedMemory(data) @@ -143,10 +143,10 @@ class TestFcc(unittest.TestCase): r_queue = MessageQueue.create_from_handle(handle) self.assertIsNotNone(r_queue.dequeue()) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_message_queue_async(self, get_runtime): STOP_EVENT.clear() - yr.log.get_logger = get_new_logger + yuanrong.log.get_logger = get_new_logger data = bytearray((10 * 1024 * 1024 + 2) * 10) shared_buffer = MockSharedMemory(data) mock_runtime = Mock() diff --git a/api/python/yr/tests/test_function_handler.py b/api/python/yuanrong/tests/test_function_handler.py similarity index 95% rename from api/python/yr/tests/test_function_handler.py rename to api/python/yuanrong/tests/test_function_handler.py index 864a260..ef7fcea 100644 --- a/api/python/yr/tests/test_function_handler.py +++ b/api/python/yuanrong/tests/test_function_handler.py @@ -19,11 +19,11 @@ import logging import inspect from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.executor.function_handler import FunctionHandler -from yr.code_manager import CodeManager -from yr.serialization import Serialization -from yr.err_type import ErrorCode -from yr.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType +from yuanrong.executor.function_handler import FunctionHandler +from yuanrong.code_manager import CodeManager +from yuanrong.serialization import Serialization +from yuanrong.err_type import ErrorCode +from yuanrong.libruntime_pb2 import FunctionMeta, LanguageType, InvokeType, ApiType logger = logging.getLogger(__name__) @@ -45,7 +45,7 @@ class TestFunctionExecutor(TestCase): isGenerator=False, isAsync=False) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load_code') def test_execute_function(self, mock_load_code, mock_logger): mock_logger.return_value = logger @@ -128,7 +128,7 @@ class TestFunctionExecutor(TestCase): err = self.handler.shutdown(10) self.assertTrue(err.error_code == ErrorCode.ERR_OK, err.error_code) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") @patch.object(CodeManager(), 'load_code') def test_execute_async_function(self, mock_load_code, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_functionsdk.py b/api/python/yuanrong/tests/test_functionsdk.py similarity index 95% rename from api/python/yr/tests/test_functionsdk.py rename to api/python/yuanrong/tests/test_functionsdk.py index 0514894..45540f6 100644 --- a/api/python/yr/tests/test_functionsdk.py +++ b/api/python/yuanrong/tests/test_functionsdk.py @@ -18,11 +18,11 @@ import os import json import logging from logging import handlers -from yr.functionsdk import context -from yr.functionsdk import function -from yr.functionsdk import utils -from yr.functionsdk import logger as sdklogger -from yr.functionsdk import logger_manager +from yuanrong.functionsdk import context +from yuanrong.functionsdk import function +from yuanrong.functionsdk import utils +from yuanrong.functionsdk import logger as sdklogger +from yuanrong.functionsdk import logger_manager from unittest import TestCase, main from unittest.mock import Mock, patch import os @@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) class TestFunctionSdk(TestCase): - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_context(self, mock_logger): mock_logger.return_value = logger @@ -57,8 +57,8 @@ class TestFunctionSdk(TestCase): self.assertEqual(invoke_context.get_trace_id(), "12345") self.assertEqual(invoke_context.getUserData("TEST_ENV_KEY"), "test_env_value") - @patch("yr.log.get_logger") - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_invoke(self, get_runtime, mock_logger): mock_logger.return_value = logger @@ -96,8 +96,8 @@ class TestFunctionSdk(TestCase): with self.assertRaises(TypeError): function.Function(func_name) - @patch("yr.log.get_logger") - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.log.get_logger") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_invoke_alias(self, get_runtime, mock_logger): mock_logger.return_value = logger @@ -135,7 +135,7 @@ class TestFunctionSdk(TestCase): with self.assertRaises(TypeError): function.Function(func_name) - @patch("yr.log.get_logger") + @patch("yuanrong.log.get_logger") def test_private_function(self, mock_logger): mock_logger.return_value = logger diff --git a/api/python/yr/tests/test_generator.py b/api/python/yuanrong/tests/test_generator.py similarity index 90% rename from api/python/yr/tests/test_generator.py rename to api/python/yuanrong/tests/test_generator.py index ffd7273..36c4bc2 100644 --- a/api/python/yr/tests/test_generator.py +++ b/api/python/yuanrong/tests/test_generator.py @@ -20,10 +20,10 @@ import logging from unittest.mock import Mock, patch from concurrent.futures import Future -import yr -from yr.fnruntime import GeneratorEndError -from yr.generator import ObjectRefGenerator -from yr.object_ref import ObjectRef +import yuanrong +from yuanrong.fnruntime import GeneratorEndError +from yuanrong.generator import ObjectRefGenerator +from yuanrong.object_ref import ObjectRef logger = logging.getLogger(__name__) @@ -78,8 +78,8 @@ class testObjectRef(unittest.TestCase): obj.set_data("data") self.assertEqual(obj.get_future().result(), "data") - @patch('yr.runtime_holder.global_runtime.get_runtime') - @patch("yr.log.get_logger") + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') + @patch("yuanrong.log.get_logger") def test_get(self, mock_logger, get_runtime): mock_logger.return_value = logger mock_runtime = Mock() @@ -98,7 +98,7 @@ class TestObjectRefGenerator(unittest.TestCase): def setUp(self): pass - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_iter(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.return_value = 'test_object_id' @@ -108,7 +108,7 @@ class TestObjectRefGenerator(unittest.TestCase): ObjectRef(generator_id, need_incre=False)) self.assertEqual(iter(generator), generator) - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_next_sync(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.return_value = 'test_object_id' @@ -119,7 +119,7 @@ class TestObjectRefGenerator(unittest.TestCase): self.assertEqual(generator._next_sync().id, 'test_object_id') print("finished test_next_sync") - @patch('yr.runtime_holder.global_runtime.get_runtime') + @patch('yuanrong.runtime_holder.global_runtime.get_runtime') def test_next_sync_with_exception(self, get_runtime): mock_runtime = Mock() mock_runtime.peek_object_ref_stream.side_effect = GeneratorEndError("failed") diff --git a/api/python/yr/tests/test_instance_manager.py b/api/python/yuanrong/tests/test_instance_manager.py similarity index 95% rename from api/python/yr/tests/test_instance_manager.py rename to api/python/yuanrong/tests/test_instance_manager.py index a8a3a13..ed90f1f 100644 --- a/api/python/yr/tests/test_instance_manager.py +++ b/api/python/yuanrong/tests/test_instance_manager.py @@ -15,7 +15,7 @@ # limitations under the License. import unittest -from yr.executor.instance_manager import InstanceManager, InstancePackage +from yuanrong.executor.instance_manager import InstanceManager, InstancePackage class TestInstanceManager(unittest.TestCase): def setUp(self) -> None: diff --git a/api/python/yr/tests/test_local_mode.py b/api/python/yuanrong/tests/test_local_mode.py similarity index 88% rename from api/python/yr/tests/test_local_mode.py rename to api/python/yuanrong/tests/test_local_mode.py index f18713d..899b34d 100644 --- a/api/python/yr/tests/test_local_mode.py +++ b/api/python/yuanrong/tests/test_local_mode.py @@ -17,15 +17,15 @@ from unittest import TestCase, main import time import concurrent.futures -import yr -from yr.object_ref import ObjectRef -from yr.exception import YRInvokeError -from yr.local_mode.local_mode_runtime import LocalModeRuntime -from yr.local_mode import local_client, instance_manager -from yr.local_mode.instance import Resource, Instance -from yr.local_mode.task_spec import TaskSpec -from yr.local_mode.local_object_store import LocalObjectStore -from yr.runtime import SetParam +import yuanrong +from yuanrong.object_ref import ObjectRef +from yuanrong.exception import YRInvokeError +from yuanrong.local_mode.local_mode_runtime import LocalModeRuntime +from yuanrong.local_mode import local_client, instance_manager +from yuanrong.local_mode.instance import Resource, Instance +from yuanrong.local_mode.task_spec import TaskSpec +from yuanrong.local_mode.local_object_store import LocalObjectStore +from yuanrong.runtime import SetParam class Mock(object): @@ -37,15 +37,15 @@ class TestApi(TestCase): pass def test_local_mode_base(self): - @yr.invoke + @yuanrong.invoke def func(x): return x - yr.init(yr.Config(local_mode=True, log_level="DEBUG")) - assert yr.get(func.invoke(1)) == 1 - assert yr.get(func.invoke(func.invoke(1))) == 1 + yuanrong.init(yuanrong.Config(local_mode=True, log_level="DEBUG")) + assert yuanrong.get(func.invoke(1)) == 1 + assert yuanrong.get(func.invoke(func.invoke(1))) == 1 - @yr.instance + @yuanrong.instance class Counter: cnt = 0 @@ -61,28 +61,28 @@ class TestApi(TestCase): return self.cnt c = Counter.invoke() - assert yr.get(c.get.invoke()) == 0 - assert yr.get(c.add.invoke()) == 1 + assert yuanrong.get(c.get.invoke()) == 0 + assert yuanrong.get(c.add.invoke()) == 1 obj_id = c.add.invoke() - ready, _ = yr.wait(obj_id, 1, 2) + ready, _ = yuanrong.wait(obj_id, 1, 2) self.assertTrue(len(ready) == 1, len(ready)) - assert yr.get(ready[0]) == 2 + assert yuanrong.get(ready[0]) == 2 obj_id = c.delay.invoke() - yr.cancel(obj_id) + yuanrong.cancel(obj_id) obj_id = ObjectRef(object_id="noid") with self.assertRaises(RuntimeError): - yr.cancel(obj_id) + yuanrong.cancel(obj_id) obj = func.invoke(1) def cb(): return obj.on_complete(cb) - self.assertEqual(yr.get(obj), 1) + self.assertEqual(yuanrong.get(obj), 1) def test_local_mode_runtime(self): lr = LocalModeRuntime() @@ -281,7 +281,7 @@ class TestApi(TestCase): trace_id="trace1234", ) instance_id, _ = ins_mgr.scale_out(task, res) - self.assertIn("yr-api-obj", instance_id) + self.assertIn("yuanrong-api-obj", instance_id) get_ins = ins_mgr.get_instances(res) self.assertEqual(len(get_ins), 1, len(get_ins)) diff --git a/api/python/yr/tests/test_metrics.py b/api/python/yuanrong/tests/test_metrics.py similarity index 93% rename from api/python/yr/tests/test_metrics.py rename to api/python/yuanrong/tests/test_metrics.py index 9a829e5..4e8e4f0 100644 --- a/api/python/yr/tests/test_metrics.py +++ b/api/python/yuanrong/tests/test_metrics.py @@ -17,13 +17,13 @@ from unittest import TestCase, main from unittest.mock import Mock, patch -from yr.config_manager import ConfigManager -from yr.config import Config -from yr import Gauge, UInt64Counter, DoubleCounter +from yuanrong.config_manager import ConfigManager +from yuanrong.config import Config +from yuanrong import Gauge, UInt64Counter, DoubleCounter class TestMetrics(TestCase): - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_gauge(self, get_runtime): mock_runtime = Mock() mock_runtime.report_gauge.side_effect = RuntimeError("mock exception") @@ -56,7 +56,7 @@ class TestMetrics(TestCase): ConfigManager().init(Config(is_driver=False, ds_address="127.0.0.1:31222")) data.set(1) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_uint64_counter(self, get_runtime): mock_runtime = Mock() mock_runtime.set_uint64_counter.side_effect = RuntimeError("mock exception") @@ -97,7 +97,7 @@ class TestMetrics(TestCase): ConfigManager().init(Config(is_driver=False, ds_address="127.0.0.1:31222")) self.assertEqual(data.get_value(), 10) - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_double_counter(self, get_runtime): mock_runtime = Mock() mock_runtime.set_double_counter.side_effect = RuntimeError("mock exception") diff --git a/api/python/yr/tests/test_runtime_env.py b/api/python/yuanrong/tests/test_runtime_env.py similarity index 99% rename from api/python/yr/tests/test_runtime_env.py rename to api/python/yuanrong/tests/test_runtime_env.py index 7636370..7ae7a04 100644 --- a/api/python/yr/tests/test_runtime_env.py +++ b/api/python/yuanrong/tests/test_runtime_env.py @@ -20,7 +20,7 @@ import tempfile import unittest from unittest.mock import patch, Mock -from yr import runtime_env, InvokeOptions +from yuanrong import runtime_env, InvokeOptions class TestPut(unittest.TestCase): diff --git a/api/python/yr/tests/test_serialization.py b/api/python/yuanrong/tests/test_serialization.py similarity index 93% rename from api/python/yr/tests/test_serialization.py rename to api/python/yuanrong/tests/test_serialization.py index 68d66d1..e278ff9 100644 --- a/api/python/yr/tests/test_serialization.py +++ b/api/python/yuanrong/tests/test_serialization.py @@ -17,9 +17,9 @@ import unittest import pickle from unittest.mock import patch, Mock -from yr.common import constants -from yr.serialization import Serialization -from yr.fnruntime import write_to_cbuffer +from yuanrong.common import constants +from yuanrong.serialization import Serialization +from yuanrong.fnruntime import write_to_cbuffer import numpy as np @@ -27,7 +27,7 @@ class TestApi(unittest.TestCase): def setUp(self) -> None: pass - @patch("yr.runtime_holder.global_runtime.get_runtime") + @patch("yuanrong.runtime_holder.global_runtime.get_runtime") def test_serialize_base(self, get_runtime): mock_runtime = Mock() mock_runtime.increase_global_reference.return_value = None diff --git a/docs/deploy/deploy_processes/parameters.md b/docs/deploy/deploy_processes/parameters.md index 1be2cd5..bb330c3 100644 --- a/docs/deploy/deploy_processes/parameters.md +++ b/docs/deploy/deploy_processes/parameters.md @@ -232,6 +232,8 @@ | `--etcd_compact_retention` | etcd 压缩的 revision 数量阈值。 | ``100000`` | 选填。| | `--etcd_target_name_override` | etcd TLS 证书域名。 | ``""`` | 用于 etcd TLS 证书校验,需要与实际的证书保存一致。 | +(security-params)= + ## 安全配置 启动脚本配置参数如下: diff --git a/docs/images/deploy_in_process_mode_1.png b/docs/images/deploy_in_process_mode_1.png index 91bfc068e65a2ef1ea5b9e3506037f476a521049..9a66c5a0120fc0f620813dfcf7a64206907e8933 100644 GIT binary patch literal 30902 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 literal 97193 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%0AN`k{ArOb%aj`jZVg&=bYY(6LzE7hLxE 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 diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/C++/Stream.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/C++/Stream.rst index c5eda07..9bbbed0 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/C++/Stream.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/C++/Stream.rst @@ -130,6 +130,7 @@ Stream 关闭后,生产者不能再被使用。 .. code-block:: cpp + producer->Close(); 抛出: @@ -191,7 +192,7 @@ Stream 订阅名称。 - .. cpp:member:: std::string subscriptionName + .. cpp:member:: SubscriptionType subscriptionType 订阅类型,包含三种类型:STREAM、ROUND_ROBIN 和 KEY_PARTITIONS。 STREAM 表示订阅组中的单个消费者会消费流。 diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ProductConfig.max_stream_size.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ProducerConfig.max_stream_size.rst similarity index 100% rename from docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ProductConfig.max_stream_size.rst rename to docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ProducerConfig.max_stream_size.rst diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ResourceGroup.wait.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ResourceGroup.wait.rst index 7eda3f5..52f98c7 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ResourceGroup.wait.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.ResourceGroup.wait.rst @@ -9,7 +9,7 @@ yr.ResourceGroup.wait 参数: - **timeout_seconds** (int, 可选) - 在等待创建 ResourceGroup 结果时阻塞的超时时间。 - 默认值为 ``None``,即 ``-1``(从不超时)。取值范围为整数大于等于 ``-1``。如果它等于 ``-1``,它将无限期地等待。 + 默认值为 ``None``,即 ``-1`` (从不超时)。取值范围为整数大于等于 ``-1`` 。如果它等于 ``-1`` ,它将无限期地等待。 异常: - **ValueError** - 超时时间小于 ``-1``。 diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.extend_config.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.extend_config.rst index 5738fea..73c4c1b 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.extend_config.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.extend_config.rst @@ -1,9 +1,9 @@ -.. _extend_config: +.. _extend_config_sub: -yr.ProducerConfig.extend_config +yr.SubscriptionConfig.extend_config ------------------------------------ -.. py:attribute:: ProducerConfig.extend_config +.. py:attribute:: SubscriptionConfig.extend_config :type: Dict[str, str] 扩展配置,以字典形式存储,允许用户自定义配置项。 diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.rst index e8c3838..e638356 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.rst @@ -17,7 +17,7 @@ yr.SubscriptionConfig - 订阅类型,包括 ``STREAM``,``ROUND_ROBIN`` 和 ``KEY_PARTITIONS``。 * - :ref:`subscription_name ` - 订阅名,用于标识生产者配置中的订阅。 - * - :ref:`extend_config ` + * - :ref:`extend_config ` - 扩展配置。 **方法**: diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.subscriptionType.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.subscriptionType.rst index 2a7461e..a34d45b 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.subscriptionType.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.SubscriptionConfig.subscriptionType.rst @@ -1,7 +1,7 @@ .. _subscriptionType: yr.SubscriptionConfig.subscriptionType ------------------------------------- +-------------------------------------------- .. py:attribute:: SubscriptionConfig.subscriptionType :type: SubscriptionType diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.kv_m_write_tx.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.kv_m_write_tx.rst index ea96ca3..87b63ce 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.kv_m_write_tx.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.kv_m_write_tx.rst @@ -8,7 +8,7 @@ yr.kv_m_write_tx 参数: - **key** (List[str]) - 为保存的数据设置一组键来标识数据。使用此键查询数据时,不能为空。 - **values** (List[bytes]) - 需要存储的一组二进制数据。云外最大存储限制为 ``100`` M。 - - **m_set_param** (MSetParam,可选) 多千伏配置参数写入数据系统。包括 ``existence``、``write_mode``、``ttl_second`` 和 ``cache_type``。 + - **m_set_param** (MSetParam,可选) - 多键配置参数写入数据系统。包括 ``existence``、``write_mode``、``ttl_second`` 和 ``cache_type``。 返回: 无。 diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst index f8cf0e8..068ad08 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.CreateParam.rst @@ -31,6 +31,4 @@ yr.runtime.CreateParam yr.runtime.CreateParam.__init__ yr.runtime.CreateParam.cache_type yr.runtime.CreateParam.consistency_type - yr.runtime.CreateParam.write_mode - diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.rst index ab93026..96d4e22 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.rst @@ -19,8 +19,6 @@ yr.runtime.SetParam - 表示是否支持 Key 重复写入。 * - :ref:`ttl_second ` - 数据生命周期,超过会被删除。 - * - :ref:`write_mode ` - - 设置数据的可靠性。 **方法**: @@ -41,7 +39,6 @@ yr.runtime.SetParam yr.runtime.SetParam.cache_type yr.runtime.SetParam.existence yr.runtime.SetParam.ttl_second - yr.runtime.SetParam.write_mode yr.runtime.SetParam.__init__ diff --git a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.write_mode.rst b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.write_mode.rst index b7875f1..344f962 100644 --- a/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.write_mode.rst +++ b/docs/multi_language_function_programming_interface/api/distributed_programming/zh_cn/Python/yr.runtime.SetParam.write_mode.rst @@ -1,4 +1,4 @@ -.. _write_mode_cp: +.. _write_mode_sp: yr.runtime.SetParam.write_mode ------------------------------------ diff --git a/docs/multi_language_function_programming_interface/development_guide/data_stream/index.md b/docs/multi_language_function_programming_interface/development_guide/data_stream/index.md index 9209d77..476dca6 100644 --- a/docs/multi_language_function_programming_interface/development_guide/data_stream/index.md +++ b/docs/multi_language_function_programming_interface/development_guide/data_stream/index.md @@ -116,7 +116,11 @@ public class Main { String streamName = "this-stream"; try { // 配置流自动删除 - ProducerConfig pConfig = ProducerConfig.builder().delayFlushTimeMs(5L).pageSizeByte(1024 * 1024L).maxStreamSize(1024 * 1024 * 1024L).autoCleanup(true).build(); + ProducerConfig pConfig = ProducerConfig.builder() + .delayFlushTimeMs(5L) + .pageSizeByte(1024 * 1024L) + .maxStreamSize(1024 * 1024 * 1024L) + .autoCleanup(true).build(); // 创建生产者将隐式创建流 this-stream Producer producer = YR.createProducer(streamName, pConfig); // 关闭生产者,流 this-stream 已无生产者或消费者关联,将被自动删除 @@ -141,7 +145,7 @@ public class Main { :::: ::::: -## 生产数据 +## 生产流数据 生产者(Producer)可向流中发送数据。生产者发送的数据会先放入缓冲区,系统根据生产者配置的 Flush 策略(发送间隔一段时间或者缓冲写满)刷新缓冲使其对消费者可见。生产者不再使用时,需要主动关闭。 @@ -226,7 +230,11 @@ public class Main { String streamName = "this-stream"; try { - ProducerConfig pConfig = ProducerConfig.builder().delayFlushTimeMs(5L).pageSizeByte(1024 * 1024L).maxStreamSize(1024 * 1024 * 1024L).autoCleanup(true).build(); + ProducerConfig pConfig = ProducerConfig.builder() + .delayFlushTimeMs(5L) + .pageSizeByte(1024 * 1024L) + .maxStreamSize(1024 * 1024 * 1024L) + .autoCleanup(true).build(); Producer producer = YR.createProducer(streamName, pConfig); // 生产数据 @@ -249,7 +257,7 @@ public class Main { :::: ::::: -## 消费数据 +## 消费流数据 消费者(Consumer)可接收流中的数据,使用 `Ack` 方法确认数据接收。消费者不再使用时,需要主动关闭。 @@ -369,7 +377,11 @@ public class Main { String streamName = "this-stream"; try { - ProducerConfig pConfig = ProducerConfig.builder().delayFlushTimeMs(5L).pageSizeByte(1024 * 1024L).maxStreamSize(1024 * 1024 * 1024L).autoCleanup(true).build(); + ProducerConfig pConfig = ProducerConfig.builder() + .delayFlushTimeMs(5L) + .pageSizeByte(1024 * 1024L) + .maxStreamSize(1024 * 1024 * 1024L) + .autoCleanup(true).build(); Producer producer = YR.createProducer(streamName, pConfig); SubscriptionConfig sConfig = SubscriptionConfig.builder().subscriptionName("local-consumer").build(); diff --git a/docs/multi_language_function_programming_interface/development_guide/stateless_function/fault-tolerance.md b/docs/multi_language_function_programming_interface/development_guide/stateless_function/fault-tolerance.md index 2730a0d..018e95d 100644 --- a/docs/multi_language_function_programming_interface/development_guide/stateless_function/fault-tolerance.md +++ b/docs/multi_language_function_programming_interface/development_guide/stateless_function/fault-tolerance.md @@ -31,7 +31,7 @@ print(yr.get(result)) yr.finalize() ``` -运行程序,在函数的标准输出[日志文件](../../../observability/logs.md#函数日志)中,您将看到四行相同的输出 `run add`,表明函数执行一次失败后又重试了 `3` 次。 +运行程序,在函数的标准输出[日志](../../../observability/logs.md)文件中,您将看到四行相同的输出 `run add`,表明函数执行一次失败后又重试了 `3` 次。 ::: diff --git a/docs/snippets/install-cmd-with-whl.md b/docs/snippets/install-cmd-with-whl.md deleted file mode 100644 index 8a75d90..0000000 --- a/docs/snippets/install-cmd-with-whl.md +++ /dev/null @@ -1,3 +0,0 @@ -```bash -pip install https://openyuanrong.obs.cn-southwest-2.myhuaweicloud.com/release/0.6.0/linux/x86_64/openyuanrong-0.6.0-cp39-cp39-manylinux_2_34_x86_64.whl -``` \ No newline at end of file diff --git a/src/libruntime/gwclient/gw_client.cpp b/src/libruntime/gwclient/gw_client.cpp index bcde946..331122a 100644 --- a/src/libruntime/gwclient/gw_client.cpp +++ b/src/libruntime/gwclient/gw_client.cpp @@ -43,7 +43,6 @@ ErrorInfo ClientBuffer::Seal(const std::unordered_set &nestedIds) for (const auto &id : nestedIds) { req.add_nestedobjectids(id); } - req.set_writemode(static_cast(this->createParam_.writeMode)); req.set_consistencytype(static_cast(this->createParam_.consistencyType)); req.set_cachetype(static_cast(this->createParam_.cacheType)); return gwClient->PosixObjPut(req); @@ -885,7 +884,6 @@ PutRequest GwClient::BuildObjPutRequest(std::shared_ptr data, const std: for (const auto &id : nestedID) { req.add_nestedobjectids(id); } - req.set_writemode(static_cast(createParam.writeMode)); req.set_consistencytype(static_cast(createParam.consistencyType)); req.set_cachetype(static_cast(createParam.cacheType)); return req; diff --git a/src/libruntime/objectstore/object_store.h b/src/libruntime/objectstore/object_store.h index b72e6f8..24a28b8 100644 --- a/src/libruntime/objectstore/object_store.h +++ b/src/libruntime/objectstore/object_store.h @@ -48,7 +48,6 @@ struct RetryInfo { }; struct CreateParam { - WriteMode writeMode = WriteMode::NONE_L2_CACHE; ConsistencyType consistencyType = ConsistencyType::PRAM; CacheType cacheType = CacheType::MEMORY; }; -- Gitee From 2b34131d073349fccea886c6da4607a1ec964cfd Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:44:37 +0800 Subject: [PATCH 5/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.sh | 6 +++--- build/build.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 5cc3a5d..dda013c 100644 --- a/build.sh +++ b/build.sh @@ -166,7 +166,7 @@ function run_java_coverage_report() { } function run_python_coverage_report() { - coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yr/tests/ -name coverage.dat) + coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yuanrong/tests/ -name coverage.dat) for i in $coverage_files; do MODULE_NAME=$(basename $(dirname $i)) lcov -q -r $i 'src/*' '*pb2.py' '*tests*' 'apis*' 'cluster_mode*' 'code_manager*' -o ${BASE_DIR}/bazel-bin/api/python/${MODULE_NAME}_coverage.txt @@ -260,7 +260,7 @@ while getopts 'athr:v:S:DcCgPET:p:bm:j:gG' opt; do ;; t) BAZEL_COMMAND="test" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" install_python_requirements ;; T) @@ -293,7 +293,7 @@ while getopts 'athr:v:S:DcCgPET:p:bm:j:gG' opt; do ;; c) BAZEL_COMMAND="coverage" - BAZEL_TARGETS="//api/go:yr_go_test //test/... //api/python/yr/tests/..." + BAZEL_TARGETS="//api/go:yr_go_test //test/... //api/python/yuanrong/tests/..." BAZEL_OPTIONS="$BAZEL_OPTIONS --combined_report=lcov --nocache_test_results --instrumentation_filter=^//.*[/:] --test_tag_filters=-cgo" install_python_requirements ;; diff --git a/build/build.sh b/build/build.sh index 196238f..58b1f8f 100644 --- a/build/build.sh +++ b/build/build.sh @@ -133,7 +133,7 @@ function run_java_coverage_report() { } function run_python_coverage_report() { - coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yr/tests/ -name coverage.dat) + coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yuanrong/tests/ -name coverage.dat) for i in $coverage_files; do MODULE_NAME=$(basename $(dirname $i)) lcov -q -r $i 'src/*' '*pb2.py' '*tests*' 'apis*' 'cluster_mode*' 'code_manager*' -o ${BASE_DIR}/bazel-bin/api/python/${MODULE_NAME}_coverage.txt @@ -224,7 +224,7 @@ while getopts 'thr:v:S:DcCgPET:p:bm:j:g' opt; do case "$opt" in t) BAZEL_COMMAND="test" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" install_python_requirements ;; T) @@ -257,7 +257,7 @@ while getopts 'thr:v:S:DcCgPET:p:bm:j:g' opt; do ;; c) BAZEL_COMMAND="coverage" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" BAZEL_OPTIONS="$BAZEL_OPTIONS --combined_report=lcov --nocache_test_results --instrumentation_filter=^//.*[/:]" install_python_requirements ;; -- Gitee From 9163efc655a692f657804bc12a002e4dd6836765 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:54:46 +0800 Subject: [PATCH 6/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/python/yuanrong/fnruntime.pyx | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/api/python/yuanrong/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx index 4c534b1..e919f1f 100644 --- a/api/python/yuanrong/fnruntime.pyx +++ b/api/python/yuanrong/fnruntime.pyx @@ -268,21 +268,6 @@ cdef CAlarmInfo alarm_info_from_py(info: AlarmInfo): cdef CSetParam set_param_from_py(set_param: SetParam): cdef: CSetParam param - if set_param.existence == ExistenceOpt.NONE: - param.existence = CExistenceOpt.NONE - else: - param.existence = CExistenceOpt.NX - - if set_param.write_mode == WriteMode.NONE_L2_CACHE: - param.writeMode = CWriteMode.NONE_L2_CACHE - elif set_param.write_mode == WriteMode.WRITE_THROUGH_L2_CACHE: - param.writeMode = CWriteMode.WRITE_THROUGH_L2_CACHE - elif set_param.write_mode == WriteMode.WRITE_BACK_L2_CACHE: - param.writeMode = CWriteMode.WRITE_BACK_L2_CACHE - elif set_param.write_mode == WriteMode.NONE_L2_CACHE_EVICT: - param.writeMode = CWriteMode.NONE_L2_CACHE_EVICT - else: - param.writeMode = CWriteMode.NONE_L2_CACHE param.ttlSecond = set_param.ttl_second if set_param.cache_type == CacheType.MEMORY: -- Gitee From 9ef61da22823df0d55daa5d9d7d80217fe026fe0 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 18:06:20 +0800 Subject: [PATCH 7/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/python/yuanrong/fnruntime.pyx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/python/yuanrong/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx index e919f1f..5919edd 100644 --- a/api/python/yuanrong/fnruntime.pyx +++ b/api/python/yuanrong/fnruntime.pyx @@ -268,6 +268,10 @@ cdef CAlarmInfo alarm_info_from_py(info: AlarmInfo): cdef CSetParam set_param_from_py(set_param: SetParam): cdef: CSetParam param + if set_param.existence == ExistenceOpt.NONE: + param.existence = CExistenceOpt.NONE + else: + param.existence = CExistenceOpt.NX param.ttlSecond = set_param.ttl_second if set_param.cache_type == CacheType.MEMORY: -- Gitee From 905b072cce8b2525eaf76e0c779f9b885df19d90 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 17:44:37 +0800 Subject: [PATCH 8/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reason:修改yr为yuanrong reason:修改yr为yuanrong --- api/python/yuanrong/fnruntime.pyx | 11 ----------- build.sh | 6 +++--- build/build.sh | 6 +++--- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/api/python/yuanrong/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx index 4c534b1..5919edd 100644 --- a/api/python/yuanrong/fnruntime.pyx +++ b/api/python/yuanrong/fnruntime.pyx @@ -272,17 +272,6 @@ cdef CSetParam set_param_from_py(set_param: SetParam): param.existence = CExistenceOpt.NONE else: param.existence = CExistenceOpt.NX - - if set_param.write_mode == WriteMode.NONE_L2_CACHE: - param.writeMode = CWriteMode.NONE_L2_CACHE - elif set_param.write_mode == WriteMode.WRITE_THROUGH_L2_CACHE: - param.writeMode = CWriteMode.WRITE_THROUGH_L2_CACHE - elif set_param.write_mode == WriteMode.WRITE_BACK_L2_CACHE: - param.writeMode = CWriteMode.WRITE_BACK_L2_CACHE - elif set_param.write_mode == WriteMode.NONE_L2_CACHE_EVICT: - param.writeMode = CWriteMode.NONE_L2_CACHE_EVICT - else: - param.writeMode = CWriteMode.NONE_L2_CACHE param.ttlSecond = set_param.ttl_second if set_param.cache_type == CacheType.MEMORY: diff --git a/build.sh b/build.sh index 5cc3a5d..dda013c 100644 --- a/build.sh +++ b/build.sh @@ -166,7 +166,7 @@ function run_java_coverage_report() { } function run_python_coverage_report() { - coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yr/tests/ -name coverage.dat) + coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yuanrong/tests/ -name coverage.dat) for i in $coverage_files; do MODULE_NAME=$(basename $(dirname $i)) lcov -q -r $i 'src/*' '*pb2.py' '*tests*' 'apis*' 'cluster_mode*' 'code_manager*' -o ${BASE_DIR}/bazel-bin/api/python/${MODULE_NAME}_coverage.txt @@ -260,7 +260,7 @@ while getopts 'athr:v:S:DcCgPET:p:bm:j:gG' opt; do ;; t) BAZEL_COMMAND="test" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" install_python_requirements ;; T) @@ -293,7 +293,7 @@ while getopts 'athr:v:S:DcCgPET:p:bm:j:gG' opt; do ;; c) BAZEL_COMMAND="coverage" - BAZEL_TARGETS="//api/go:yr_go_test //test/... //api/python/yr/tests/..." + BAZEL_TARGETS="//api/go:yr_go_test //test/... //api/python/yuanrong/tests/..." BAZEL_OPTIONS="$BAZEL_OPTIONS --combined_report=lcov --nocache_test_results --instrumentation_filter=^//.*[/:] --test_tag_filters=-cgo" install_python_requirements ;; diff --git a/build/build.sh b/build/build.sh index 196238f..58b1f8f 100644 --- a/build/build.sh +++ b/build/build.sh @@ -133,7 +133,7 @@ function run_java_coverage_report() { } function run_python_coverage_report() { - coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yr/tests/ -name coverage.dat) + coverage_files=$(find bazel-out/k8-opt/testlogs/api/python/yuanrong/tests/ -name coverage.dat) for i in $coverage_files; do MODULE_NAME=$(basename $(dirname $i)) lcov -q -r $i 'src/*' '*pb2.py' '*tests*' 'apis*' 'cluster_mode*' 'code_manager*' -o ${BASE_DIR}/bazel-bin/api/python/${MODULE_NAME}_coverage.txt @@ -224,7 +224,7 @@ while getopts 'thr:v:S:DcCgPET:p:bm:j:g' opt; do case "$opt" in t) BAZEL_COMMAND="test" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" install_python_requirements ;; T) @@ -257,7 +257,7 @@ while getopts 'thr:v:S:DcCgPET:p:bm:j:g' opt; do ;; c) BAZEL_COMMAND="coverage" - BAZEL_TARGETS="//test/... //api/python/yr/tests/... //api/java:java_tests" + BAZEL_TARGETS="//test/... //api/python/yuanrong/tests/... //api/java:java_tests" BAZEL_OPTIONS="$BAZEL_OPTIONS --combined_report=lcov --nocache_test_results --instrumentation_filter=^//.*[/:]" install_python_requirements ;; -- Gitee From 0508389472fca648357e8fab094cdc7f3a1d83b5 Mon Sep 17 00:00:00 2001 From: xiaoxiawang Date: Fri, 5 Dec 2025 18:14:37 +0800 Subject: [PATCH 9/9] =?UTF-8?q?reason:=E4=BF=AE=E6=94=B9yr=E4=B8=BAyuanron?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/python/yuanrong/fnruntime.pyx | 63 ++++++------------------------- 1 file changed, 11 insertions(+), 52 deletions(-) diff --git a/api/python/yuanrong/fnruntime.pyx b/api/python/yuanrong/fnruntime.pyx index 5919edd..60dd34c 100644 --- a/api/python/yuanrong/fnruntime.pyx +++ b/api/python/yuanrong/fnruntime.pyx @@ -272,6 +272,17 @@ cdef CSetParam set_param_from_py(set_param: SetParam): param.existence = CExistenceOpt.NONE else: param.existence = CExistenceOpt.NX + + if set_param.write_mode == WriteMode.NONE_L2_CACHE: + param.writeMode = CWriteMode.NONE_L2_CACHE + elif set_param.write_mode == WriteMode.WRITE_THROUGH_L2_CACHE: + param.writeMode = CWriteMode.WRITE_THROUGH_L2_CACHE + elif set_param.write_mode == WriteMode.WRITE_BACK_L2_CACHE: + param.writeMode = CWriteMode.WRITE_BACK_L2_CACHE + elif set_param.write_mode == WriteMode.NONE_L2_CACHE_EVICT: + param.writeMode = CWriteMode.NONE_L2_CACHE_EVICT + else: + param.writeMode = CWriteMode.NONE_L2_CACHE param.ttlSecond = set_param.ttl_second if set_param.cache_type == CacheType.MEMORY: @@ -341,15 +352,6 @@ cdef CGetParams get_params_from_py(params: GetParams): c_get_params.getParams.push_back(c_get_param) return c_get_params -cdef CGroupOptions group_options_from_py(group_name: str, group_opts: GroupOptions): - cdef: - CGroupOptions c_group_options - c_group_options.groupName = group_name.encode() - c_group_options.timeout = group_opts.timeout - c_group_options.sameLifecycle = group_opts.same_lifecycle - c_group_options.strategy = group_opts.strategy - return c_group_options - cdef CFunctionGroupOptions function_group_options_from_py(function_group_opts: FunctionGroupOptions, group_size: int): cdef: CFunctionGroupOptions c_function_group_options @@ -937,7 +939,6 @@ cdef parse_invoke_opts(CInvokeOptions & opts, opt: yr.InvokeOptions, group_info: opts.maxInstances = opt.max_instances opts.isDataAffinity = opt.is_data_affinity opts.resourceGroupOpts = resource_group_options_from_py(opt.resource_group_options) - opts.groupName = opt.group_name.encode() if group_info is not None: opts.functionGroupOpts = function_group_options_from_py(opt.function_group_options, group_info.group_size) opts.groupName = group_info.group_name.encode() @@ -2585,48 +2586,6 @@ cdef class Fnruntime: with nogil: ret = CLibruntimeManager.Instance().GetLibRuntime().get().AddReturnObject(c_obj_ids) return ret - - def create_group(self, group_name: str, group_opts: GroupOptions): - cdef: - string c_group_name = group_name.encode() - CGroupOptions c_group_options - c_group_options = group_options_from_py(group_name, group_opts) - with nogil: - ret = CLibruntimeManager.Instance().GetLibRuntime().get().GroupCreate(c_group_name, c_group_options) - if not ret.OK(): - raise RuntimeError( - f"failed to create group, code: {ret.Code()}, " - f"module code: {ret.MCode()}, msg: {ret.Msg().decode()}") - - def wait_group(self, group_name: str): - cdef: - string c_group_name = group_name.encode() - with nogil: - ret = CLibruntimeManager.Instance().GetLibRuntime().get().GroupWait(c_group_name) - if not ret.OK(): - raise RuntimeError( - f"failed to wait group, code: {ret.Code()}, " - f"module code: {ret.MCode()}, msg: {ret.Msg().decode()}") - - def suspend_group(self, group_name: str): - cdef: - string c_group_name = group_name.encode() - with nogil: - ret = CLibruntimeManager.Instance().GetLibRuntime().get().GroupSuspend(c_group_name) - if not ret.OK(): - raise RuntimeError( - f"failed to suspend group, code: {ret.Code()}, " - f"module code: {ret.MCode()}, msg: {ret.Msg().decode()}") - - def resume_group(self, group_name: str): - cdef: - string c_group_name = group_name.encode() - with nogil: - ret = CLibruntimeManager.Instance().GetLibRuntime().get().GroupResume(c_group_name) - if not ret.OK(): - raise RuntimeError( - f"failed to resume group, code: {ret.Code()}, " - f"module code: {ret.MCode()}, msg: {ret.Msg().decode()}") def notify_generator_result(generator_id, index, output, error_info): -- Gitee