polaris-python 0.0.1.dev3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. polaris/__init__.py +74 -0
  2. polaris/_version.py +16 -0
  3. polaris/api/__init__.py +55 -0
  4. polaris/api/_log_file.py +232 -0
  5. polaris/api/config.py +145 -0
  6. polaris/api/consumer.py +240 -0
  7. polaris/api/log.py +414 -0
  8. polaris/api/lossless.py +73 -0
  9. polaris/api/provider.py +152 -0
  10. polaris/api/skill.py +162 -0
  11. polaris/pkg/__init__.py +15 -0
  12. polaris/pkg/common/__init__.py +15 -0
  13. polaris/pkg/common/plugin.py +33 -0
  14. polaris/pkg/config/__init__.py +15 -0
  15. polaris/pkg/config/api.py +1205 -0
  16. polaris/pkg/config/default.py +92 -0
  17. polaris/pkg/config/event.py +76 -0
  18. polaris/pkg/config/loader.py +392 -0
  19. polaris/pkg/config/stat_reporter.py +100 -0
  20. polaris/pkg/flow/__init__.py +15 -0
  21. polaris/pkg/flow/admin_server.py +104 -0
  22. polaris/pkg/flow/async_flow.py +55 -0
  23. polaris/pkg/flow/base_flow.py +111 -0
  24. polaris/pkg/flow/impl.py +1277 -0
  25. polaris/pkg/flow/lossless.py +605 -0
  26. polaris/pkg/flow/notify.py +46 -0
  27. polaris/pkg/flow/register.py +210 -0
  28. polaris/pkg/flow/skill.py +110 -0
  29. polaris/pkg/flow/sync_flow.py +20 -0
  30. polaris/pkg/model/__init__.py +15 -0
  31. polaris/pkg/model/context.py +53 -0
  32. polaris/pkg/model/contract.py +89 -0
  33. polaris/pkg/model/core.py +51 -0
  34. polaris/pkg/model/engine.py +83 -0
  35. polaris/pkg/model/error.py +94 -0
  36. polaris/pkg/model/event.py +159 -0
  37. polaris/pkg/model/lossless.py +102 -0
  38. polaris/pkg/model/rule.py +152 -0
  39. polaris/pkg/model/server.py +288 -0
  40. polaris/pkg/model/service.py +820 -0
  41. polaris/pkg/model/skill.py +179 -0
  42. polaris/pkg/model/stat.py +168 -0
  43. polaris/pkg/model/util.py +58 -0
  44. polaris/pkg/version/__init__.py +18 -0
  45. polaris/plugin/__init__.py +32 -0
  46. polaris/plugin/circuit_breaker/__init__.py +19 -0
  47. polaris/plugin/circuit_breaker/base.py +54 -0
  48. polaris/plugin/circuit_breaker/composite.py +265 -0
  49. polaris/plugin/circuit_breaker/config.py +36 -0
  50. polaris/plugin/event/__init__.py +21 -0
  51. polaris/plugin/event/pushgateway.py +202 -0
  52. polaris/plugin/load_balancer/__init__.py +24 -0
  53. polaris/plugin/load_balancer/base.py +30 -0
  54. polaris/plugin/load_balancer/random.py +39 -0
  55. polaris/plugin/load_balancer/weighted_random.py +50 -0
  56. polaris/plugin/local_registry/__init__.py +18 -0
  57. polaris/plugin/local_registry/base.py +47 -0
  58. polaris/plugin/local_registry/file_cache.py +335 -0
  59. polaris/plugin/local_registry/local_cache.py +433 -0
  60. polaris/plugin/server_connector/__init__.py +20 -0
  61. polaris/plugin/server_connector/base.py +104 -0
  62. polaris/plugin/server_connector/convert.py +149 -0
  63. polaris/plugin/server_connector/grpc_connector/__init__.py +21 -0
  64. polaris/plugin/server_connector/grpc_connector/connection.py +401 -0
  65. polaris/plugin/server_connector/grpc_connector/grpc_client.py +384 -0
  66. polaris/plugin/server_connector/grpc_connector/tls.py +45 -0
  67. polaris/plugin/service_router/__init__.py +28 -0
  68. polaris/plugin/service_router/base.py +105 -0
  69. polaris/plugin/service_router/isolated.py +35 -0
  70. polaris/plugin/service_router/metadata.py +84 -0
  71. polaris/plugin/service_router/recover.py +62 -0
  72. polaris/plugin/service_router/util.py +54 -0
  73. polaris/plugin/skill/__init__.py +16 -0
  74. polaris/plugin/skill/connector.py +127 -0
  75. polaris/plugin/skill/persistence.py +94 -0
  76. polaris/plugin/stat_reporter/__init__.py +16 -0
  77. polaris/plugin/stat_reporter/base.py +34 -0
  78. polaris/plugin/stat_reporter/prometheus.py +375 -0
  79. polaris/plugin_manager.py +146 -0
  80. polaris_python-0.0.1.dev3.dist-info/METADATA +213 -0
  81. polaris_python-0.0.1.dev3.dist-info/RECORD +84 -0
  82. polaris_python-0.0.1.dev3.dist-info/WHEEL +5 -0
  83. polaris_python-0.0.1.dev3.dist-info/licenses/LICENSE +18 -0
  84. polaris_python-0.0.1.dev3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,104 @@
1
+ # Tencent is pleased to support the open source community by making polaris-python available.
2
+ #
3
+ # Copyright (C) 2021 Tencent. All rights reserved.
4
+ #
5
+ # Licensed under the BSD 3-Clause License (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://opensource.org/licenses/BSD-3-Clause
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ """Shared admin HTTP server for stats and lossless endpoints."""
18
+
19
+ from __future__ import annotations
20
+
21
+ import time
22
+
23
+ from aiohttp import web
24
+
25
+ import polaris.api.log as logger
26
+ from polaris.pkg.config.stat_reporter import AdminConfig
27
+ from polaris.pkg.model.error import ErrorCode, SDKError
28
+
29
+ admin_logger = logger.get_logger("admin")
30
+
31
+
32
+ class AdminHttpServer:
33
+ """Expose one aiohttp application for every SDK component on the admin port."""
34
+
35
+ def __init__(self, admin_config: AdminConfig):
36
+ self.admin_config = admin_config
37
+ self.app = web.Application(middlewares=[self._log_request])
38
+ self.runner = None
39
+ self.port = None
40
+ self._routes = {}
41
+ self._started = False
42
+
43
+ @staticmethod
44
+ @web.middleware
45
+ async def _log_request(request, handler):
46
+ started = time.monotonic()
47
+ try:
48
+ response = await handler(request)
49
+ except Exception as error:
50
+ admin_logger.error("admin http %s %s failed: %s", request.method, request.path, error)
51
+ raise
52
+ admin_logger.debug(
53
+ "admin http %s %s status=%d cost=%.3fms",
54
+ request.method, request.path, response.status, (time.monotonic() - started) * 1000,
55
+ )
56
+ return response
57
+
58
+ def add_route(self, method: str, path: str, handler) -> None:
59
+ key = (method, path)
60
+ if key in self._routes:
61
+ raise SDKError(ErrorCode.ErrCodeAPIInvalidArgument,
62
+ f"duplicated admin HTTP route {method} {path}")
63
+ self._routes[key] = handler
64
+ self.app.router.add_route(method, path, handler)
65
+
66
+ def has_routes(self) -> bool:
67
+ return bool(self._routes)
68
+
69
+ async def start(self) -> None:
70
+ """Bind the configured admin address once all routes have been added."""
71
+ if self._started:
72
+ return
73
+ if not self._routes or self.admin_config.port is None or self.admin_config.port < 0:
74
+ admin_logger.info(
75
+ "admin http server disabled host=%s port=%s routes=%d",
76
+ self.admin_config.host, self.admin_config.port, len(self._routes),
77
+ )
78
+ return
79
+ self.runner = web.AppRunner(self.app, access_log=None)
80
+ await self.runner.setup()
81
+ site = web.TCPSite(self.runner, self.admin_config.host, self.admin_config.port)
82
+ try:
83
+ await site.start()
84
+ except OSError as error:
85
+ await self.runner.cleanup()
86
+ self.runner = None
87
+ raise SDKError(ErrorCode.ErrCodeAPIInvalidConfig,
88
+ f"Cannot bind admin listener {self.admin_config.host}:{self.admin_config.port}: {error}") from error
89
+ self.port = site._server.sockets[0].getsockname()[1]
90
+ self._started = True
91
+ admin_logger.info(
92
+ "admin http server listening host=%s port=%s routes=%d",
93
+ self.admin_config.host, self.port, len(self._routes),
94
+ )
95
+
96
+ async def close(self) -> None:
97
+ started = self._started
98
+ if self.runner is not None:
99
+ await self.runner.cleanup()
100
+ self.runner = None
101
+ self._started = False
102
+ self.port = None
103
+ if started:
104
+ admin_logger.info("admin http server stopped")
@@ -0,0 +1,55 @@
1
+ # Tencent is pleased to support the open source community by making polaris-python available.
2
+ #
3
+ # Copyright (C) 2021 Tencent. All rights reserved.
4
+ #
5
+ # Licensed under the BSD 3-Clause License (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://opensource.org/licenses/BSD-3-Clause
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software distributed
12
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
14
+ # specific language governing permissions and limitations under the License.
15
+
16
+ from polaris.pkg.model.service import GetOneInstanceRequest, GetInstancesRequest
17
+ from polaris.pkg.flow.base_flow import CacheFilter, CacheResult
18
+ from polaris.pkg.flow.impl import Engine
19
+ from polaris.pkg.flow.base_flow import get_load_cache_values
20
+
21
+
22
+ class FutureRequest:
23
+ def __init__(self, request: GetOneInstanceRequest, hash_value: int, do_load_balance: bool):
24
+ self.request = request
25
+ self.hash_value = hash_value
26
+ self.do_load_balance = do_load_balance
27
+
28
+
29
+ class AsyncFlowFuture:
30
+ def __init__(self, request: FutureRequest, filter_request: CacheFilter, redirect_times: int, engine: Engine):
31
+ self.request = request
32
+ self.filter_request = filter_request
33
+ self.redirect_times = redirect_times
34
+ self.engine = engine
35
+
36
+
37
+ class AsyncEngine(Engine):
38
+
39
+ def create_async_flow_future(self, req: FutureRequest):
40
+ future = AsyncFlowFuture(request=req)
41
+ future.engine = AsyncEngine
42
+ return future
43
+
44
+ async def async_get_instances(self, req: GetInstancesRequest, do_balance: bool):
45
+ req = self.set_default_value_for_instances_request(req)
46
+ async_future = self.create_async_flow_future(req)
47
+ async_future.filter_request = self.instance_request_to_cache_filter(req=req, redirect_service=None)
48
+ request = async_future.filter_request
49
+ result = await get_load_cache_values(self.registry, request, True)
50
+ return result
51
+
52
+ async def async_get_one_instance(self, req: GetOneInstanceRequest):
53
+ instance_request = GetInstancesRequest(flow_id=req.flow_id, service=req.service, namespace=req.namespave,
54
+ timeout=req.timeout)
55
+ return await self.async_get_instances(instance_request, True)
@@ -0,0 +1,111 @@
1
+ # Tencent is pleased to support the open source community by making polaris-python available.
2
+ #
3
+ # Copyright (C) 2021 Tencent. All rights reserved.
4
+ #
5
+ # Licensed under the BSD 3-Clause License (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://opensource.org/licenses/BSD-3-Clause
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software distributed
12
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the
14
+ # specific language governing permissions and limitations under the License.
15
+
16
+ from polaris.plugin.local_registry.local_cache import InstanceFilter
17
+ from polaris.pkg.model.rule import ServiceRule
18
+ from polaris.pkg.model.service import ServiceInstances
19
+ from polaris.plugin.local_registry.local_cache import LocalCache
20
+ from polaris.pkg.model.core import ServiceKey
21
+ from polaris.plugin.local_registry.local_cache import ServiceUpdateRequest
22
+ from typing import Dict
23
+ from polaris.api.log import get_logger
24
+ import copy
25
+ from polaris.plugin.circuit_breaker.composite import CircuitBreakResult
26
+ from polaris.pkg.model.error import ErrorCode, SDKError
27
+
28
+ logger = get_logger("cache")
29
+
30
+
31
+ class RealTimeLimitTask:
32
+ def __init__(self, svc: ServiceKey = None, ins_id: str = None, host: str = None, port: int = None,
33
+ cb_name: str = None):
34
+ self.service_key = svc
35
+ self.instance_id = ins_id
36
+ self.host = host
37
+ self.port = port
38
+ self.cb_name = cb_name
39
+
40
+ def get_host(self):
41
+ return self.host
42
+
43
+ def get_port(self):
44
+ return self.port
45
+
46
+ def get_instance_id(self):
47
+ return self.instance_id
48
+
49
+ def get_service_key(self):
50
+ return self.service_key
51
+
52
+ def get_cb_name(self):
53
+ return self.cb_name
54
+
55
+
56
+ class CacheFilter:
57
+ def __init__(self, namespace: str, service: str, dest_instance_fileter: InstanceFilter):
58
+ self.namespace = namespace
59
+ self.service = service
60
+ self.desc_instances_filter = dest_instance_fileter
61
+
62
+ def to_context_key(self):
63
+ pass
64
+
65
+
66
+ class CacheResult:
67
+ def __init__(self, source_route_rule: ServiceRule = None, dest_route_rule: ServiceRule = None,
68
+ dest_instances: ServiceInstances = None):
69
+ self.source_route_rule = source_route_rule
70
+ self.dest_route_rule = dest_route_rule
71
+ self.dest_instances = dest_instances
72
+ self.combineContext = ""
73
+
74
+
75
+ async def get_load_cache_values(registry: LocalCache, filters: CacheFilter, load: bool,
76
+ use_discover_cache=True, timeout=None) -> CacheResult:
77
+ result = CacheResult()
78
+ instances = registry.get_instances(instance_filter=filters.desc_instances_filter)
79
+ if instances and instances.is_initialized():
80
+ result.dest_instances = copy.copy(instances)
81
+ elif load:
82
+ logger.debug("miss local cache and begin to load remote value for %s",
83
+ filters.desc_instances_filter.__dict__)
84
+ try:
85
+ await registry.load_instances(filters.service, filters.namespace, use_discover_cache, timeout=timeout)
86
+ except SDKError as error:
87
+ if error.err_code not in (ErrorCode.ErrCodeNetworkError, ErrorCode.ErrCodeAPITimeoutError):
88
+ raise
89
+ fallback_filter = copy.copy(filters.desc_instances_filter)
90
+ fallback_filter.include_cache = True
91
+ instances = registry.get_instances(fallback_filter)
92
+ if instances is None:
93
+ raise
94
+ logger.warning("remote discovery unavailable; using local snapshot for %s/%s",
95
+ filters.namespace, filters.service)
96
+ else:
97
+ instances = registry.get_instances(instance_filter=filters.desc_instances_filter)
98
+ result.dest_instances = copy.copy(instances) if instances is not None else None
99
+ else:
100
+ return None
101
+ return result
102
+
103
+
104
+ def build_instance_property(now, allowed_request: int, instances):
105
+ pass
106
+
107
+
108
+ def build_service_update_request(svc: ServiceKey, results: Dict[str, CircuitBreakResult]) -> ServiceUpdateRequest:
109
+ request = ServiceUpdateRequest(service=svc.get_service(), namespace=svc.get_namespace())
110
+ for cb_name, result in results.items():
111
+ pass