opengris-scaler 1.12.11__cp310-cp310-manylinux_2_28_x86_64.whl → 1.12.13__cp310-cp310-manylinux_2_28_x86_64.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.
Potentially problematic release.
This version of opengris-scaler might be problematic. Click here for more details.
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/METADATA +5 -3
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/RECORD +26 -26
- scaler/client/client.py +26 -3
- scaler/entry_points/scheduler.py +4 -4
- scaler/io/ymq/_ymq.so +0 -0
- scaler/io/ymq/epoll_context.cpp +1 -1
- scaler/io/ymq/event_loop_thread.h +6 -0
- scaler/io/ymq/io_context.cpp +2 -3
- scaler/io/ymq/io_socket.cpp +7 -8
- scaler/io/ymq/message_connection_tcp.cpp +3 -0
- scaler/io/ymq/message_connection_tcp.h +3 -2
- scaler/io/ymq/pymod_ymq/io_context.h +5 -4
- scaler/io/ymq/pymod_ymq/io_socket.h +26 -16
- scaler/io/ymq/pymod_ymq/ymq.h +9 -9
- scaler/object_storage/object_storage_server.h +0 -2
- scaler/object_storage/object_storage_server.so +0 -0
- scaler/version.txt +1 -1
- scaler/worker/agent/processor/processor.py +6 -0
- scaler/worker/agent/processor_holder.py +2 -0
- scaler/worker/agent/processor_manager.py +3 -0
- scaler/worker/worker.py +1 -0
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/WHEEL +0 -0
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/entry_points.txt +0 -0
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/licenses/LICENSE +0 -0
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/licenses/LICENSE.spdx +0 -0
- {opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: opengris-scaler
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.13
|
|
4
4
|
Summary: OpenGRIS Scaler Distribution Framework
|
|
5
5
|
Author-Email: Citi <opensource@citi.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -25,7 +25,7 @@ Provides-Extra: uvloop
|
|
|
25
25
|
Requires-Dist: uvloop; platform_system != "Windows" and extra == "uvloop"
|
|
26
26
|
Provides-Extra: gui
|
|
27
27
|
Requires-Dist: nicegui[plotly]==2.24.2; python_version == "3.8" and extra == "gui"
|
|
28
|
-
Requires-Dist: nicegui[plotly]==3.0.
|
|
28
|
+
Requires-Dist: nicegui[plotly]==3.0.4; python_version >= "3.9" and extra == "gui"
|
|
29
29
|
Provides-Extra: graphblas
|
|
30
30
|
Requires-Dist: python-graphblas; extra == "graphblas"
|
|
31
31
|
Requires-Dist: numpy==1.24.4; python_version == "3.8" and extra == "graphblas"
|
|
@@ -33,7 +33,7 @@ Requires-Dist: numpy==2.0.2; python_version == "3.9" and extra == "graphblas"
|
|
|
33
33
|
Requires-Dist: numpy==2.2.6; python_version >= "3.10" and extra == "graphblas"
|
|
34
34
|
Provides-Extra: all
|
|
35
35
|
Requires-Dist: nicegui[plotly]==2.24.2; python_version == "3.8" and extra == "all"
|
|
36
|
-
Requires-Dist: nicegui[plotly]==3.0.
|
|
36
|
+
Requires-Dist: nicegui[plotly]==3.0.4; python_version >= "3.9" and extra == "all"
|
|
37
37
|
Requires-Dist: python-graphblas; extra == "all"
|
|
38
38
|
Requires-Dist: numpy==1.24.4; python_version == "3.8" and extra == "all"
|
|
39
39
|
Requires-Dist: numpy==2.0.2; python_version == "3.9" and extra == "all"
|
|
@@ -365,6 +365,8 @@ with Client(address="tcp://127.0.0.1:2345") as client:
|
|
|
365
365
|
print(future.result()) # 21
|
|
366
366
|
```
|
|
367
367
|
|
|
368
|
+
**Note**: When creating a `Client` inside a task (nested client), the `address` parameter is optional. If omitted, the client automatically uses the scheduler address from the worker context. If provided, the specified address takes precedence.
|
|
369
|
+
|
|
368
370
|
## Task Routing and Capability Management
|
|
369
371
|
|
|
370
372
|
> **Note**: This feature is experimental and may change in future releases.
|
|
@@ -3,9 +3,9 @@ opengris_scaler.libs/libkj-1-094aa318.1.0.so,sha256=dRbFbTaca-2vf1SS5LDL3WNfPzoE
|
|
|
3
3
|
scaler/CMakeLists.txt,sha256=60rkhpiwy0F-DSsRX_6nRrjYQvQ1Jp9mGp8fZsi006k,305
|
|
4
4
|
scaler/__init__.py,sha256=nZU5QZ9oW2YIaGwm3-r-6dfmirTVzZpDPDNtX-ITCV4,513
|
|
5
5
|
scaler/about.py,sha256=OBcfSvHO0P3mWaa2Ci4WEOTbH7is-3uYymScxgZPxyg,161
|
|
6
|
-
scaler/version.txt,sha256=
|
|
6
|
+
scaler/version.txt,sha256=F6PMSyppBgeF1s1ced3yCqk9L1U1rOtqGWHlqvHibuU,8
|
|
7
7
|
scaler/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
scaler/client/client.py,sha256=
|
|
8
|
+
scaler/client/client.py,sha256=9WWclvdsouYPREGwmkWWA3gpz5DVFEAD6HKbtXr3Jx8,25506
|
|
9
9
|
scaler/client/future.py,sha256=fOl5g4Is4E5jtvO0kmRk4uUs_eUjSjMmyniYhWMAH4w,10041
|
|
10
10
|
scaler/client/object_buffer.py,sha256=MBjz1Rf6ufgTyjMYoV8V78xpezot0aUit41nj-5kV50,4670
|
|
11
11
|
scaler/client/object_reference.py,sha256=Pow064leLlO6OhfW-yyEjcesbzn22ijqGBSQlsQNEtU,606
|
|
@@ -44,7 +44,7 @@ scaler/config/types/zmq.py,sha256=0VODax61H-4PxN6rIeWKlMXOHiW5elVSt1zc-UF0SL8,25
|
|
|
44
44
|
scaler/entry_points/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
45
|
scaler/entry_points/cluster.py,sha256=5jPO_fFVe8IiSiAkLhLZ0mXJKXiYUWjvpXjEGlcgwW4,5779
|
|
46
46
|
scaler/entry_points/object_storage_server.py,sha256=YGDl9-ws0oha1YXXl3gFH660B-IV2o06gCp41zUovdg,1418
|
|
47
|
-
scaler/entry_points/scheduler.py,sha256=
|
|
47
|
+
scaler/entry_points/scheduler.py,sha256=uJkmr1M3gzTEWmntdDr0f0-zls2V91vRPANahRjFj0c,6003
|
|
48
48
|
scaler/entry_points/top.py,sha256=pqOPD27HeZrnMvqw4cOF4bvZ-sxgg7zp_Q1v8VtbC4A,9542
|
|
49
49
|
scaler/entry_points/webui.py,sha256=ypcrE6Lr4rUX_qM0qSsv-dX7kzZiMMWTe5GL-Ol45BI,1067
|
|
50
50
|
scaler/entry_points/worker_adapter_native.py,sha256=1If3xEu2YsnRIrAmcP-MXmnVTF7hescDed4jTL3vkzM,5412
|
|
@@ -61,29 +61,29 @@ scaler/io/utility.py,sha256=yFq8-X47RfWp344HpRfqc_3XF3c6vewKPLi73e248s8,1189
|
|
|
61
61
|
scaler/io/ymq/CMakeLists.txt,sha256=znJS9ru-tjtn7Lv8RN1RJZVPhlHaE5AKS44z1Nnj_vE,1987
|
|
62
62
|
scaler/io/ymq/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
63
|
scaler/io/ymq/_ymq.pyi,sha256=HYLhjYhHTOgjffpAnlqyCSdUjEvKVRP7Slv8vIgGdkI,3036
|
|
64
|
-
scaler/io/ymq/_ymq.so,sha256=
|
|
64
|
+
scaler/io/ymq/_ymq.so,sha256=6Jv1CR2aeZ6EAy0v5zzBjuutrkCSfjX6Oy2FhialeS4,1110016
|
|
65
65
|
scaler/io/ymq/bytes.h,sha256=fxaZ0NMwzJC-agotCZbGizMs-IgPW4VWG4raeWBXC5I,2931
|
|
66
66
|
scaler/io/ymq/common.h,sha256=XmYnfVeaIGZU3-gI2slw4uZyRrz807ANJXSQTf1joEY,711
|
|
67
67
|
scaler/io/ymq/configuration.h,sha256=VvtSSGgD5dCOKc-gvtsqSBDoagaRnfnUS7jueDVsn9U,1951
|
|
68
|
-
scaler/io/ymq/epoll_context.cpp,sha256=
|
|
68
|
+
scaler/io/ymq/epoll_context.cpp,sha256=BE-Ol2p8-t61BajaEzLK-B2ABNNDiExVbb0Ym9BjbVA,4938
|
|
69
69
|
scaler/io/ymq/epoll_context.h,sha256=0Cu840Utq6puRHCTVctCWpfdfNpUFcZJqw5D7e7hzSs,2641
|
|
70
70
|
scaler/io/ymq/error.h,sha256=BUb55lcKou20u9e_GHZ0WEmlHJeC3VQWEzW-yTuRCTQ,5552
|
|
71
71
|
scaler/io/ymq/event_loop.h,sha256=CDvcOszqtDSqkFt3t9hsT8n9HStbIchk7UO1u-3CTL0,1652
|
|
72
72
|
scaler/io/ymq/event_loop_thread.cpp,sha256=0aYMmgpg8g6mmC-Ked2F3GCHNGJNXZAZLPobEQqu7g4,1801
|
|
73
|
-
scaler/io/ymq/event_loop_thread.h,sha256=
|
|
73
|
+
scaler/io/ymq/event_loop_thread.h,sha256=XNsVDH7r4tDBlU4VstrwMBGgOMOEsoDn7qLFjox1nEg,1683
|
|
74
74
|
scaler/io/ymq/event_manager.h,sha256=WTRkNg8j8J_tLNU2ZtilVogC2EoLT5LrLIezeox5i80,2066
|
|
75
75
|
scaler/io/ymq/interruptive_concurrent_queue.h,sha256=_hZkdfImpXT0L1fNsb-EfAYbaeTjQNmMGVMyZ6gT2Gg,4750
|
|
76
|
-
scaler/io/ymq/io_context.cpp,sha256=
|
|
76
|
+
scaler/io/ymq/io_context.cpp,sha256=nVjZCYE8zeYkWScDeYsXEh8AW9qhyORodn7etaT3-Vs,3080
|
|
77
77
|
scaler/io/ymq/io_context.h,sha256=eYyXCnHWWfSPVykvvA0sdjjAnKq2y768t3Exg0EU_IA,1248
|
|
78
|
-
scaler/io/ymq/io_socket.cpp,sha256=
|
|
78
|
+
scaler/io/ymq/io_socket.cpp,sha256=Li6P-7R80YwduaL59_D2wQ36twufdIIXaP7IS46zSwQ,11506
|
|
79
79
|
scaler/io/ymq/io_socket.h,sha256=lWqfJHZg6OGxz16x2NwKKbtvjfErrC4IUP3puw72Nwg,4953
|
|
80
80
|
scaler/io/ymq/iocp_context.cpp,sha256=SRGEn5MVoWl8JUIO2sZDUQi6AbhrXfhQ-aRoWiaF2SY,3103
|
|
81
81
|
scaler/io/ymq/iocp_context.h,sha256=pAwrs8XZWHIskEdQyA5BrISxsiSzfW6r9J873pBMs4Q,2731
|
|
82
82
|
scaler/io/ymq/logging.h,sha256=TJFeawseU8zkWiSC_yS3dO2i0oKAWAZFzyb_vk0tU7Q,5421
|
|
83
83
|
scaler/io/ymq/message.h,sha256=yBAd5BIeDttWqseyoUBPKPnD1qT05o_vlqEN3J53lP4,241
|
|
84
84
|
scaler/io/ymq/message_connection.h,sha256=dvkIjMt31gPFephJURtxcqm7TFAWZ3y0ZvuekXFL3_Q,350
|
|
85
|
-
scaler/io/ymq/message_connection_tcp.cpp,sha256=
|
|
86
|
-
scaler/io/ymq/message_connection_tcp.h,sha256=
|
|
85
|
+
scaler/io/ymq/message_connection_tcp.cpp,sha256=yxIFZBzShzAEUUtHXhSj6sy_udRC-Jw-TwvZk3Vio6Q,21902
|
|
86
|
+
scaler/io/ymq/message_connection_tcp.h,sha256=C7jo2fVeHqdhIk8cAaVNAnnF8IyIIJT0EZC1Sf_MDe4,2743
|
|
87
87
|
scaler/io/ymq/network_utils.h,sha256=qebEdeKYpztZLI02c25eqcRmFMqBZN3GEaE81fiyBF8,4142
|
|
88
88
|
scaler/io/ymq/readme.md,sha256=gzjJJovTVjV0e-4QpjrscT0gmtDiPjszAIlVt5upshg,3739
|
|
89
89
|
scaler/io/ymq/simple_interface.cpp,sha256=BpsjGW3xGCajnQDa9UN8GJA_Xu15LfJTU4IRnsGOA04,2912
|
|
@@ -101,12 +101,12 @@ scaler/io/ymq/ymq.py,sha256=d8bxU0h2maQvIkiJgGeTD-QynCOa4JwYCwuVfxqq9AE,4658
|
|
|
101
101
|
scaler/io/ymq/pymod_ymq/bytes.h,sha256=srlYnWibw2a9mgulzCc5H-7TnMob8QWA2ChAdbZ4bxw,3135
|
|
102
102
|
scaler/io/ymq/pymod_ymq/exception.h,sha256=4nfUpc8VJDRZeBvgmOZN_j0FHmryZTbxzzBrWQKhhG4,3573
|
|
103
103
|
scaler/io/ymq/pymod_ymq/gil.h,sha256=YdFOBWEBC1TSYmIvzr5NDZf-xmm49PMGqYP2nh-5Fk8,403
|
|
104
|
-
scaler/io/ymq/pymod_ymq/io_context.h,sha256=
|
|
105
|
-
scaler/io/ymq/pymod_ymq/io_socket.h,sha256=
|
|
104
|
+
scaler/io/ymq/pymod_ymq/io_context.h,sha256=03DcUlHCZyk78rNJmxRFgjxFOiQLWCq5FLm-gEENi0k,5014
|
|
105
|
+
scaler/io/ymq/pymod_ymq/io_socket.h,sha256=1M7NhhyP3alEJ9fnS04cwY9Frz4b5gZ19qPCCGxSeLQ,9674
|
|
106
106
|
scaler/io/ymq/pymod_ymq/message.h,sha256=gqYKDnNCK9W1q0gte0pGfbmx119gQvcWBaJzIFdRsuc,3039
|
|
107
107
|
scaler/io/ymq/pymod_ymq/python.h,sha256=wb0-WNF4occ4nDphSoUI47_OrfVPP72eLlGC_B59b7c,4284
|
|
108
108
|
scaler/io/ymq/pymod_ymq/ymq.cpp,sha256=LoxL5ViLK0zyWRSYfmZn0QO-0vLw3xVZrRQJ5rWtc4w,526
|
|
109
|
-
scaler/io/ymq/pymod_ymq/ymq.h,sha256=
|
|
109
|
+
scaler/io/ymq/pymod_ymq/ymq.h,sha256=p3cNnvgv8R1ThCBM56G-OlINWZsm1Xd0o14kpItG9gw,11892
|
|
110
110
|
scaler/io/ymq/third_party/concurrentqueue.h,sha256=yN268t8miyojar0bBBPIEjMI3DlHVZci2eufkDDA0FA,152819
|
|
111
111
|
scaler/object_storage/CMakeLists.txt,sha256=qexi6sKNGieaRhKkO65kxdaQrKRY-8adYKlvc42aEew,1566
|
|
112
112
|
scaler/object_storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -119,8 +119,8 @@ scaler/object_storage/message.h,sha256=8KCts7n36jys3PiX09-lPtfa6DjfHI_2hYvled9af
|
|
|
119
119
|
scaler/object_storage/object_manager.cpp,sha256=cxNv9vOkCC910hlF5JF0mOUwTho8ieA1RJgF_P4e3ho,3083
|
|
120
120
|
scaler/object_storage/object_manager.h,sha256=TkxICR8_20I-tkHwnMO0VpLWkm24vOEabrmQG6hdnmQ,1696
|
|
121
121
|
scaler/object_storage/object_storage_server.cpp,sha256=ZiMpLOakguD3p108OVRf0XQmsZtHN5tw5Fs46Pq0nwA,13794
|
|
122
|
-
scaler/object_storage/object_storage_server.h,sha256=
|
|
123
|
-
scaler/object_storage/object_storage_server.so,sha256=
|
|
122
|
+
scaler/object_storage/object_storage_server.h,sha256=X8W4QFHgNUmBOsJ-JfADfMu9Z4pti8OFYyMR3C1Am1Q,4244
|
|
123
|
+
scaler/object_storage/object_storage_server.so,sha256=9CJBS73SmJpp5bcvt6funF6jU5ctHfqMQgzR8lZBbug,1349217
|
|
124
124
|
scaler/object_storage/pymod_object_storage_server.cpp,sha256=D09p81wZF6WnV35I6od3iDhgktV20v82CRR_tQ90ROs,3811
|
|
125
125
|
scaler/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
126
126
|
scaler/protocol/introduction.md,sha256=G8oRzui4KmSlfFUu70y24tTmDmfEKBkog9tFVUn7G1U,5406
|
|
@@ -200,18 +200,18 @@ scaler/utility/queues/async_sorted_priority_queue.py,sha256=f4k1dO34LcJkq1OMLbI_
|
|
|
200
200
|
scaler/utility/queues/indexed_queue.py,sha256=MLFkXWEZ8HaJC-gKZD9F9gf-oXL_lJ7O317FnTWFCuQ,3077
|
|
201
201
|
scaler/worker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
202
202
|
scaler/worker/preload.py,sha256=gjkNx1IvRBk_bJeYCBN_tD6Vyw8n0LJbnI1O2qwZz18,3086
|
|
203
|
-
scaler/worker/worker.py,sha256=
|
|
203
|
+
scaler/worker/worker.py,sha256=Zj4kGey1FAgF7vzY6R0q2Xp48cJei4jh9IMyi9N2NDc,10937
|
|
204
204
|
scaler/worker/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
205
205
|
scaler/worker/agent/heartbeat_manager.py,sha256=R-pWuH8xixqHsANGVv_pFkJtFie4S2VNHlFa4olWfJA,4730
|
|
206
206
|
scaler/worker/agent/mixins.py,sha256=fhTytvyBHB3ydIy-J1_q4bvp4fsCTUPAU2ZDC5rCQFI,4067
|
|
207
|
-
scaler/worker/agent/processor_holder.py,sha256=
|
|
208
|
-
scaler/worker/agent/processor_manager.py,sha256=
|
|
207
|
+
scaler/worker/agent/processor_holder.py,sha256=TZoTG6C7NkSmYkg7MfVEmK2AIxaRBqLVp1ZMZwNlfuE,5065
|
|
208
|
+
scaler/worker/agent/processor_manager.py,sha256=BBBf7DirMvCgfVXzBRgyX76QE8lFnsjIW3KL465bpo0,13375
|
|
209
209
|
scaler/worker/agent/profiling_manager.py,sha256=77qF_b8LhfKszQ5eNZiUUc9FqcBCH5Uo1jpEklbCExg,3977
|
|
210
210
|
scaler/worker/agent/task_manager.py,sha256=7X1J9MW8Ib58t1dBb84yhkZVo60zezKn-Z5M2oF-RoA,6149
|
|
211
211
|
scaler/worker/agent/timeout_manager.py,sha256=HAUBUOhFh8QTeuYTrhInr0mX1O12PGbODBkkUtcLReQ,602
|
|
212
212
|
scaler/worker/agent/processor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
213
213
|
scaler/worker/agent/processor/object_cache.py,sha256=6IlU1hAV3ZgapNj9UMXJI_eN7uwVbCvVh9Vhlv6arEs,3857
|
|
214
|
-
scaler/worker/agent/processor/processor.py,sha256=
|
|
214
|
+
scaler/worker/agent/processor/processor.py,sha256=DZgJEvUXKYbpqCO72rCAhYaTJa-ZilShPe_ympy1ksc,11104
|
|
215
215
|
scaler/worker/agent/processor/streaming_buffer.py,sha256=aOBfbC3VOveYvpR6HIqBcTCXPc--dY0-q1IGIAXeI1k,863
|
|
216
216
|
scaler/worker_adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
217
217
|
scaler/worker_adapter/native.py,sha256=FYlw7TFY5zn2re-9bJ5SnTCAAsx7I_4HEbRJIkRlz9E,6179
|
|
@@ -222,10 +222,10 @@ scaler/worker_adapter/symphony/message.py,sha256=HOonEASua8e-uwpPVxprjyl1rrYmFJa
|
|
|
222
222
|
scaler/worker_adapter/symphony/task_manager.py,sha256=phgx8dtAv-5ynsvsmG4DKcSlENz4b340FE6LDUWyMwo,12139
|
|
223
223
|
scaler/worker_adapter/symphony/worker.py,sha256=VIDOoqVXbwrjHYN3lghbQpEIuCbVJUgiYsBknrI-0oc,7957
|
|
224
224
|
scaler/worker_adapter/symphony/worker_adapter.py,sha256=eAAD1O0Uz1pjEdQPPl2fd8kyaF6q-aqCRrg48k1ocUU,5455
|
|
225
|
-
opengris_scaler-1.12.
|
|
226
|
-
opengris_scaler-1.12.
|
|
227
|
-
opengris_scaler-1.12.
|
|
228
|
-
opengris_scaler-1.12.
|
|
229
|
-
opengris_scaler-1.12.
|
|
230
|
-
opengris_scaler-1.12.
|
|
231
|
-
opengris_scaler-1.12.
|
|
225
|
+
opengris_scaler-1.12.13.dist-info/METADATA,sha256=ETTF9ysLYGYoViBW74q-0f5eprUiesTpR2y7hl0ijwk,27234
|
|
226
|
+
opengris_scaler-1.12.13.dist-info/WHEEL,sha256=WfUIOrZZjmphW6XvWWOC-3zHgyiL7DZcrARpY3z4EcQ,118
|
|
227
|
+
opengris_scaler-1.12.13.dist-info/entry_points.txt,sha256=KROw4kj4Z6p8YuOgpOFt5spHskm87A7Z-fOOffT4tVU,446
|
|
228
|
+
opengris_scaler-1.12.13.dist-info/RECORD,,
|
|
229
|
+
opengris_scaler-1.12.13.dist-info/licenses/LICENSE,sha256=xudC0jta6OXJkSHiLzzQQU50HIwSo0G97exO280dtR8,11345
|
|
230
|
+
opengris_scaler-1.12.13.dist-info/licenses/LICENSE.spdx,sha256=i49Qe6AmXxuvocKyExEFduvdh-NQ5YuxdHs515G8VOQ,225
|
|
231
|
+
opengris_scaler-1.12.13.dist-info/licenses/NOTICE,sha256=JUHdG2ssq0nP2QsqPM8X2eJhfJhK_lemIvDBqBRXrMo,286
|
scaler/client/client.py
CHANGED
|
@@ -51,7 +51,7 @@ class _CallNode:
|
|
|
51
51
|
class Client:
|
|
52
52
|
def __init__(
|
|
53
53
|
self,
|
|
54
|
-
address: str,
|
|
54
|
+
address: Optional[str] = None,
|
|
55
55
|
profiling: bool = False,
|
|
56
56
|
timeout_seconds: int = DEFAULT_CLIENT_TIMEOUT_SECONDS,
|
|
57
57
|
heartbeat_interval_seconds: int = DEFAULT_HEARTBEAT_INTERVAL_SECONDS,
|
|
@@ -61,8 +61,9 @@ class Client:
|
|
|
61
61
|
"""
|
|
62
62
|
The Scaler Client used to send tasks to a scheduler.
|
|
63
63
|
|
|
64
|
-
:param address: Address of Scheduler to submit work to
|
|
65
|
-
|
|
64
|
+
:param address: Address of Scheduler to submit work to. If None, will attempt to auto-detect
|
|
65
|
+
when running inside a worker context.
|
|
66
|
+
:type address: Optional[str]
|
|
66
67
|
:param profiling: If True, the returned futures will have the `task_duration()` property enabled.
|
|
67
68
|
:type profiling: bool
|
|
68
69
|
:param timeout_seconds: Seconds until heartbeat times out
|
|
@@ -72,6 +73,7 @@ class Client:
|
|
|
72
73
|
:param stream_output: If True, stdout/stderr will be streamed to client during task execution
|
|
73
74
|
:type stream_output: bool
|
|
74
75
|
"""
|
|
76
|
+
address = self._resolve_scheduler_address(address)
|
|
75
77
|
self.__initialize__(address, profiling, timeout_seconds, heartbeat_interval_seconds, serializer, stream_output)
|
|
76
78
|
|
|
77
79
|
def __initialize__(
|
|
@@ -380,6 +382,10 @@ class Client:
|
|
|
380
382
|
disconnect from connected scheduler, this will not shut down the scheduler
|
|
381
383
|
"""
|
|
382
384
|
|
|
385
|
+
# Handle case where client wasn't fully initialized
|
|
386
|
+
if not hasattr(self, "_stop_event"):
|
|
387
|
+
return
|
|
388
|
+
|
|
383
389
|
if self._stop_event.is_set():
|
|
384
390
|
self.__destroy()
|
|
385
391
|
return
|
|
@@ -633,3 +639,20 @@ class Client:
|
|
|
633
639
|
assert current_task is not None
|
|
634
640
|
|
|
635
641
|
return retrieve_task_flags_from_task(current_task).priority
|
|
642
|
+
|
|
643
|
+
def _resolve_scheduler_address(self, address: Optional[str]) -> str:
|
|
644
|
+
"""Resolve the scheduler address based on the provided address and worker context."""
|
|
645
|
+
# Provided address always takes precedence
|
|
646
|
+
if address is not None:
|
|
647
|
+
return address
|
|
648
|
+
|
|
649
|
+
# No address provided, check if we're running inside a worker context
|
|
650
|
+
current_processor = Processor.get_current_processor()
|
|
651
|
+
if current_processor is None:
|
|
652
|
+
raise ValueError(
|
|
653
|
+
"No scheduler address provided and not running inside a worker context. "
|
|
654
|
+
"Please provide a scheduler address when creating the Client outside of a worker."
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
# Return the scheduler address from the current processor
|
|
658
|
+
return current_processor.scheduler_address().to_address()
|
scaler/entry_points/scheduler.py
CHANGED
|
@@ -93,7 +93,10 @@ def main():
|
|
|
93
93
|
|
|
94
94
|
scheduler_config = load_config(SchedulerConfig, args.config, args, section_name="scheduler")
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
object_storage_address = scheduler_config.object_storage_address
|
|
97
|
+
object_storage = None
|
|
98
|
+
|
|
99
|
+
if object_storage_address is None:
|
|
97
100
|
object_storage_address = ObjectStorageConfig(
|
|
98
101
|
host=scheduler_config.scheduler_address.host, port=get_available_tcp_port()
|
|
99
102
|
)
|
|
@@ -105,9 +108,6 @@ def main():
|
|
|
105
108
|
)
|
|
106
109
|
object_storage.start()
|
|
107
110
|
object_storage.wait_until_ready() # object storage should be ready before starting the cluster
|
|
108
|
-
else:
|
|
109
|
-
object_storage_address = scheduler_config.object_storage_address
|
|
110
|
-
object_storage = None
|
|
111
111
|
|
|
112
112
|
scheduler = SchedulerProcess(
|
|
113
113
|
address=scheduler_config.scheduler_address,
|
scaler/io/ymq/_ymq.so
CHANGED
|
Binary file
|
scaler/io/ymq/epoll_context.cpp
CHANGED
|
@@ -41,7 +41,7 @@ void EpollContext::loop()
|
|
|
41
41
|
// todo: investigate better error handling
|
|
42
42
|
// the epoll thread is not expected to receive signals(?)
|
|
43
43
|
// but occasionally does (e.g. sigwinch) and we shouldn't stop the thread in that case
|
|
44
|
-
|
|
44
|
+
return;
|
|
45
45
|
case EBADF:
|
|
46
46
|
case EFAULT:
|
|
47
47
|
case EINVAL:
|
scaler/io/ymq/io_context.cpp
CHANGED
|
@@ -76,15 +76,14 @@ void IOContext::removeIOSocket(std::shared_ptr<IOSocket>& socket) noexcept
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
if (id != -1) {
|
|
79
|
-
|
|
79
|
+
_threads[id]->tryJoin();
|
|
80
80
|
_threads[id] = std::make_shared<EventLoopThread>();
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
void IOContext::requestIOSocketStop(std::shared_ptr<IOSocket> socket) noexcept
|
|
85
85
|
{
|
|
86
|
-
socket->_eventLoopThread->_eventLoop.executeNow(
|
|
87
|
-
[socket] { socket->_eventLoopThread->_eventLoop.executeLater([socket] { socket->requestStop(); }); });
|
|
86
|
+
socket->_eventLoopThread->_eventLoop.executeNow([socket] { socket->requestStop(); });
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
IOContext::~IOContext() noexcept
|
scaler/io/ymq/io_socket.cpp
CHANGED
|
@@ -145,14 +145,11 @@ void IOSocket::bindTo(std::string networkAddress, BindReturnCallback onBindRetur
|
|
|
145
145
|
void IOSocket::closeConnection(Identity remoteSocketIdentity) noexcept
|
|
146
146
|
{
|
|
147
147
|
_eventLoopThread->_eventLoop.executeNow([this, remoteIdentity = std::move(remoteSocketIdentity)] {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (_identityToConnection.contains(remoteIdentity))
|
|
154
|
-
_identityToConnection[remoteIdentity]->disconnect();
|
|
155
|
-
});
|
|
148
|
+
if (_stopped) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (_identityToConnection.contains(remoteIdentity))
|
|
152
|
+
_identityToConnection[remoteIdentity]->disconnect();
|
|
156
153
|
});
|
|
157
154
|
}
|
|
158
155
|
|
|
@@ -179,6 +176,7 @@ void IOSocket::onConnectionDisconnected(MessageConnectionTCP* conn, bool keepInB
|
|
|
179
176
|
this->_pendingRecvMessages->pop();
|
|
180
177
|
}
|
|
181
178
|
}
|
|
179
|
+
_eventLoopThread->_eventLoop.executeLater([conn = std::move(connPtr)]() {});
|
|
182
180
|
_unestablishedConnection.pop_back();
|
|
183
181
|
return;
|
|
184
182
|
}
|
|
@@ -244,6 +242,7 @@ void IOSocket::onConnectionIdentityReceived(MessageConnectionTCP* conn) noexcept
|
|
|
244
242
|
assert(targetConn->_receivedReadOperations.empty());
|
|
245
243
|
targetConn->_receivedReadOperations = std::move((*c)->_receivedReadOperations);
|
|
246
244
|
|
|
245
|
+
assert((*c)->_connFd == 0);
|
|
247
246
|
_unestablishedConnection.erase(c);
|
|
248
247
|
}
|
|
249
248
|
|
|
@@ -321,6 +321,9 @@ void MessageConnectionTCP::onRead()
|
|
|
321
321
|
return _remoteIOSocketIdentity;
|
|
322
322
|
})
|
|
323
323
|
.and_then([this, maybeCloseConn](const std::string&) -> std::optional<std::string> {
|
|
324
|
+
if (!_connFd) {
|
|
325
|
+
return _remoteIOSocketIdentity;
|
|
326
|
+
}
|
|
324
327
|
auto _ = tryReadMessages()
|
|
325
328
|
.or_else(maybeCloseConn) //
|
|
326
329
|
.and_then([this]() -> std::expected<void, IOError> {
|
|
@@ -105,20 +105,21 @@ static PyObject* PyIOContext_createIOSocket(PyIOContext* self, PyObject* args, P
|
|
|
105
105
|
if (!ioSocket)
|
|
106
106
|
return nullptr;
|
|
107
107
|
|
|
108
|
-
Py_INCREF(callback);
|
|
109
|
-
|
|
110
108
|
try {
|
|
111
109
|
// ensure the fields are init
|
|
112
110
|
new (&ioSocket->socket) std::shared_ptr<IOSocket>();
|
|
113
111
|
new (&ioSocket->ioContext) std::shared_ptr<IOContext>();
|
|
114
112
|
ioSocket->ioContext = self->ioContext;
|
|
115
113
|
|
|
114
|
+
Py_INCREF(callback);
|
|
115
|
+
|
|
116
116
|
self->ioContext->createIOSocket(
|
|
117
117
|
std::string(identity, identityLen), socketType, [callback, ioSocket](auto socket) {
|
|
118
118
|
AcquireGIL _;
|
|
119
119
|
|
|
120
|
-
ioSocket->socket
|
|
121
|
-
OwnedPyObject _result
|
|
120
|
+
ioSocket->socket = socket;
|
|
121
|
+
OwnedPyObject _result = PyObject_CallFunctionObjArgs(callback, *ioSocket, nullptr);
|
|
122
|
+
|
|
122
123
|
Py_DECREF(callback);
|
|
123
124
|
});
|
|
124
125
|
} catch (...) {
|
|
@@ -57,8 +57,8 @@ static PyObject* PyIOSocket_send(PyIOSocket* self, PyObject* args, PyObject* kwa
|
|
|
57
57
|
if (!state)
|
|
58
58
|
return nullptr;
|
|
59
59
|
|
|
60
|
-
PyObject* callback
|
|
61
|
-
PyMessage* message
|
|
60
|
+
PyObject* callback = nullptr;
|
|
61
|
+
PyMessage* message = nullptr;
|
|
62
62
|
|
|
63
63
|
// empty str -> positional only
|
|
64
64
|
const char* kwlist[] = {"", "message", nullptr};
|
|
@@ -73,9 +73,9 @@ static PyObject* PyIOSocket_send(PyIOSocket* self, PyObject* args, PyObject* kwa
|
|
|
73
73
|
auto address = message->address.is_none() ? Bytes() : std::move(message->address->bytes);
|
|
74
74
|
auto payload = std::move(message->payload->bytes);
|
|
75
75
|
|
|
76
|
-
Py_INCREF(callback);
|
|
77
|
-
|
|
78
76
|
try {
|
|
77
|
+
Py_INCREF(callback);
|
|
78
|
+
|
|
79
79
|
self->socket->sendMessage(
|
|
80
80
|
{.address = std::move(address), .payload = std::move(payload)}, [callback, state](auto result) {
|
|
81
81
|
AcquireGIL _;
|
|
@@ -108,35 +108,45 @@ static PyObject* PyIOSocket_recv(PyIOSocket* self, PyObject* args, PyObject* kwa
|
|
|
108
108
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", (char**)kwlist, &callback))
|
|
109
109
|
return nullptr;
|
|
110
110
|
|
|
111
|
-
Py_INCREF(callback);
|
|
112
|
-
|
|
113
111
|
try {
|
|
112
|
+
Py_INCREF(callback);
|
|
113
|
+
|
|
114
114
|
self->socket->recvMessage([callback, state](std::pair<Message, Error> result) {
|
|
115
115
|
AcquireGIL _;
|
|
116
116
|
|
|
117
117
|
if (result.second._errorCode != Error::ErrorCode::Uninit) {
|
|
118
118
|
OwnedPyObject obj = YMQException_createFromCoreError(state, &result.second);
|
|
119
119
|
OwnedPyObject _ = PyObject_CallFunctionObjArgs(callback, *obj, nullptr);
|
|
120
|
+
Py_DECREF(callback);
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
auto message = result.first;
|
|
124
125
|
OwnedPyObject<PyBytesYMQ> address = (PyBytesYMQ*)PyObject_CallNoArgs(*state->PyBytesYMQType);
|
|
125
|
-
if (!address)
|
|
126
|
-
|
|
126
|
+
if (!address) {
|
|
127
|
+
completeCallbackWithRaisedException(callback);
|
|
128
|
+
Py_DECREF(callback);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
127
131
|
|
|
128
132
|
address->bytes = std::move(message.address);
|
|
129
133
|
|
|
130
134
|
OwnedPyObject<PyBytesYMQ> payload = (PyBytesYMQ*)PyObject_CallNoArgs(*state->PyBytesYMQType);
|
|
131
|
-
if (!payload)
|
|
132
|
-
|
|
135
|
+
if (!payload) {
|
|
136
|
+
completeCallbackWithRaisedException(callback);
|
|
137
|
+
Py_DECREF(callback);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
133
140
|
|
|
134
141
|
payload->bytes = std::move(message.payload);
|
|
135
142
|
|
|
136
143
|
OwnedPyObject<PyMessage> pyMessage =
|
|
137
144
|
(PyMessage*)PyObject_CallFunction(*state->PyMessageType, "OO", *address, *payload);
|
|
138
|
-
if (!pyMessage)
|
|
139
|
-
|
|
145
|
+
if (!pyMessage) {
|
|
146
|
+
completeCallbackWithRaisedException(callback);
|
|
147
|
+
Py_DECREF(callback);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
140
150
|
|
|
141
151
|
OwnedPyObject _result = PyObject_CallFunctionObjArgs(callback, *pyMessage, nullptr);
|
|
142
152
|
Py_DECREF(callback);
|
|
@@ -162,9 +172,9 @@ static PyObject* PyIOSocket_bind(PyIOSocket* self, PyObject* args, PyObject* kwa
|
|
|
162
172
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os#", (char**)kwlist, &callback, &address, &addressLen))
|
|
163
173
|
return nullptr;
|
|
164
174
|
|
|
165
|
-
Py_INCREF(callback);
|
|
166
|
-
|
|
167
175
|
try {
|
|
176
|
+
Py_INCREF(callback);
|
|
177
|
+
|
|
168
178
|
self->socket->bindTo(std::string(address, addressLen), [callback, state](auto result) {
|
|
169
179
|
AcquireGIL _;
|
|
170
180
|
|
|
@@ -198,9 +208,9 @@ static PyObject* PyIOSocket_connect(PyIOSocket* self, PyObject* args, PyObject*
|
|
|
198
208
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os#", (char**)kwlist, &callback, &address, &addressLen))
|
|
199
209
|
return nullptr;
|
|
200
210
|
|
|
201
|
-
Py_INCREF(callback);
|
|
202
|
-
|
|
203
211
|
try {
|
|
212
|
+
Py_INCREF(callback);
|
|
213
|
+
|
|
204
214
|
self->socket->connectTo(std::string(address, addressLen), [callback, state](auto result) {
|
|
205
215
|
AcquireGIL _;
|
|
206
216
|
|
scaler/io/ymq/pymod_ymq/ymq.h
CHANGED
|
@@ -20,13 +20,13 @@ struct YMQState {
|
|
|
20
20
|
OwnedPyObject<> enumModule; // Reference to the enum module
|
|
21
21
|
OwnedPyObject<> asyncioModule; // Reference to the asyncio module
|
|
22
22
|
|
|
23
|
-
OwnedPyObject<> PyIOSocketEnumType;
|
|
24
|
-
OwnedPyObject<> PyErrorCodeType;
|
|
25
|
-
OwnedPyObject<> PyBytesYMQType;
|
|
26
|
-
OwnedPyObject<> PyMessageType;
|
|
27
|
-
OwnedPyObject<> PyIOSocketType;
|
|
28
|
-
OwnedPyObject<> PyIOContextType;
|
|
29
|
-
OwnedPyObject<> PyExceptionType;
|
|
23
|
+
OwnedPyObject<> PyIOSocketEnumType; // Reference to the IOSocketType enum
|
|
24
|
+
OwnedPyObject<> PyErrorCodeType; // Reference to the Error enum
|
|
25
|
+
OwnedPyObject<> PyBytesYMQType; // Reference to the PyBytesYMQ type
|
|
26
|
+
OwnedPyObject<> PyMessageType; // Reference to the Message type
|
|
27
|
+
OwnedPyObject<> PyIOSocketType; // Reference to the IOSocket type
|
|
28
|
+
OwnedPyObject<> PyIOContextType; // Reference to the IOContext type
|
|
29
|
+
OwnedPyObject<> PyExceptionType; // Reference to the Exception type
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
static YMQState* YMQStateFromSelf(PyObject* self)
|
|
@@ -76,8 +76,8 @@ std::expected<PyObject*, PyObject*> YMQ_GetRaisedException()
|
|
|
76
76
|
|
|
77
77
|
void completeCallbackWithRaisedException(PyObject* callback)
|
|
78
78
|
{
|
|
79
|
-
auto result
|
|
80
|
-
OwnedPyObject _
|
|
79
|
+
auto result = YMQ_GetRaisedException();
|
|
80
|
+
OwnedPyObject _ = PyObject_CallFunctionObjArgs(callback, result.value_or(result.error()), nullptr);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// First-Party
|
|
Binary file
|
scaler/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.12.
|
|
1
|
+
1.12.13
|
|
@@ -37,6 +37,7 @@ class Processor(multiprocessing.get_context("spawn").Process): # type: ignore
|
|
|
37
37
|
self,
|
|
38
38
|
event_loop: str,
|
|
39
39
|
agent_address: ZMQConfig,
|
|
40
|
+
scheduler_address: ZMQConfig,
|
|
40
41
|
storage_address: ObjectStorageConfig,
|
|
41
42
|
preload: Optional[str],
|
|
42
43
|
resume_event: Optional[EventType],
|
|
@@ -50,6 +51,7 @@ class Processor(multiprocessing.get_context("spawn").Process): # type: ignore
|
|
|
50
51
|
|
|
51
52
|
self._event_loop = event_loop
|
|
52
53
|
self._agent_address = agent_address
|
|
54
|
+
self._scheduler_address = scheduler_address
|
|
53
55
|
self._storage_address = storage_address
|
|
54
56
|
self._preload = preload
|
|
55
57
|
|
|
@@ -74,6 +76,10 @@ class Processor(multiprocessing.get_context("spawn").Process): # type: ignore
|
|
|
74
76
|
"""Returns the current Processor instance controlling the current process, if any."""
|
|
75
77
|
return _current_processor.get()
|
|
76
78
|
|
|
79
|
+
def scheduler_address(self) -> ZMQConfig:
|
|
80
|
+
"""Returns the scheduler address this processor's worker is connected to."""
|
|
81
|
+
return self._scheduler_address
|
|
82
|
+
|
|
77
83
|
def current_task(self) -> Optional[Task]:
|
|
78
84
|
return self._current_task
|
|
79
85
|
|
|
@@ -19,6 +19,7 @@ class ProcessorHolder:
|
|
|
19
19
|
self,
|
|
20
20
|
event_loop: str,
|
|
21
21
|
agent_address: ZMQConfig,
|
|
22
|
+
scheduler_address: ZMQConfig,
|
|
22
23
|
storage_address: ObjectStorageConfig,
|
|
23
24
|
preload: Optional[str],
|
|
24
25
|
garbage_collect_interval_seconds: int,
|
|
@@ -43,6 +44,7 @@ class ProcessorHolder:
|
|
|
43
44
|
self._processor = Processor(
|
|
44
45
|
event_loop=event_loop,
|
|
45
46
|
agent_address=agent_address,
|
|
47
|
+
scheduler_address=scheduler_address,
|
|
46
48
|
storage_address=storage_address,
|
|
47
49
|
preload=preload,
|
|
48
50
|
resume_event=self._resume_event,
|
|
@@ -23,6 +23,7 @@ class VanillaProcessorManager(ProcessorManager):
|
|
|
23
23
|
identity: WorkerID,
|
|
24
24
|
event_loop: str,
|
|
25
25
|
address_internal: ZMQConfig,
|
|
26
|
+
scheduler_address: ZMQConfig,
|
|
26
27
|
preload: Optional[str],
|
|
27
28
|
garbage_collect_interval_seconds: int,
|
|
28
29
|
trim_memory_threshold_bytes: int,
|
|
@@ -34,6 +35,7 @@ class VanillaProcessorManager(ProcessorManager):
|
|
|
34
35
|
|
|
35
36
|
self._identity = identity
|
|
36
37
|
self._event_loop = event_loop
|
|
38
|
+
self._scheduler_address = scheduler_address
|
|
37
39
|
self._preload = preload
|
|
38
40
|
|
|
39
41
|
self._garbage_collect_interval_seconds = garbage_collect_interval_seconds
|
|
@@ -299,6 +301,7 @@ class VanillaProcessorManager(ProcessorManager):
|
|
|
299
301
|
self._current_holder = ProcessorHolder(
|
|
300
302
|
self._event_loop,
|
|
301
303
|
self._address_internal,
|
|
304
|
+
self._scheduler_address,
|
|
302
305
|
storage_address,
|
|
303
306
|
self._preload,
|
|
304
307
|
self._garbage_collect_interval_seconds,
|
scaler/worker/worker.py
CHANGED
|
@@ -139,6 +139,7 @@ class Worker(multiprocessing.get_context("spawn").Process): # type: ignore
|
|
|
139
139
|
identity=self._ident,
|
|
140
140
|
event_loop=self._event_loop,
|
|
141
141
|
address_internal=self._address_internal,
|
|
142
|
+
scheduler_address=self._address,
|
|
142
143
|
preload=self._preload,
|
|
143
144
|
garbage_collect_interval_seconds=self._garbage_collect_interval_seconds,
|
|
144
145
|
trim_memory_threshold_bytes=self._trim_memory_threshold_bytes,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opengris_scaler-1.12.11.dist-info → opengris_scaler-1.12.13.dist-info}/licenses/LICENSE.spdx
RENAMED
|
File without changes
|
|
File without changes
|