ringo-task-queue 0.1.0.dev7__py3-none-win_amd64.whl → 0.1.0.dev8__py3-none-win_amd64.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.
- ringo_task_queue/_proto/ringo/v1/queue_pb2.py +26 -22
- ringo_task_queue/_proto/ringo/v1/queue_pb2_grpc.py +45 -0
- ringo_task_queue/_supervisor_child.py +91 -0
- ringo_task_queue/_supervisor_ipc.py +81 -0
- ringo_task_queue/_supervisor_policy.py +182 -0
- ringo_task_queue/_supervisor_process.py +562 -0
- ringo_task_queue/_supervisor_runtime.py +420 -0
- ringo_task_queue/_supervisor_watchdog.py +429 -0
- ringo_task_queue/_version.py +2 -2
- ringo_task_queue/bin/manifest.json +7 -7
- ringo_task_queue/bin/ringo-task-queue-windows-amd64.exe +0 -0
- ringo_task_queue/client.py +135 -72
- ringo_task_queue/shared.py +60 -8
- ringo_task_queue/supervisor.py +575 -0
- ringo_task_queue/worker.py +609 -272
- {ringo_task_queue-0.1.0.dev7.dist-info → ringo_task_queue-0.1.0.dev8.dist-info}/METADATA +98 -9
- ringo_task_queue-0.1.0.dev8.dist-info/RECORD +27 -0
- ringo_task_queue-0.1.0.dev7.dist-info/RECORD +0 -20
- {ringo_task_queue-0.1.0.dev7.dist-info → ringo_task_queue-0.1.0.dev8.dist-info}/WHEEL +0 -0
- {ringo_task_queue-0.1.0.dev7.dist-info → ringo_task_queue-0.1.0.dev8.dist-info}/licenses/LICENSE +0 -0
|
@@ -28,7 +28,7 @@ from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
|
28
28
|
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,ringo_task_queue/_proto/ringo/v1/queue.proto\x12\x08ringo.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"(\n\x12\x41ttachLocalRequest\x12\x12\n\ngeneration\x18\x01 \x01(\t\")\n\x13\x41ttachLocalResponse\x12\x12\n\ngeneration\x18\x01 \x01(\t\"i\n\x10NegotiateRequest\x12\x10\n\x08sdk_name\x18\x01 \x01(\t\x12\x13\n\x0bsdk_version\x18\x02 \x01(\t\x12\x16\n\x0eprotocol_major\x18\x03 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x04 \x01(\r\"\x88\x01\n\x11NegotiateResponse\x12\x16\n\x0eserver_version\x18\x01 \x01(\t\x12\x16\n\x0eprotocol_major\x18\x02 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x03 \x01(\r\x12\x14\n\x0c\x63\x61pabilities\x18\x04 \x03(\t\x12\x15\n\rsession_token\x18\x05 \x01(\t\"W\n\x0eRequestContext\x12\x16\n\x0eprotocol_major\x18\x01 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x02 \x01(\r\x12\x15\n\rsession_token\x18\x03 \x01(\t\"\xbd\x01\n\x0b\x45rrorDetail\x12!\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x13.ringo.v1.ErrorCode\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12\x35\n\x08metadata\x18\x04 \x03(\x0b\x32#.ringo.v1.ErrorDetail.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xed\x01\n\x0bRetryPolicy\x12\x14\n\x0cmax_attempts\x18\x01 \x01(\r\x12)\n\x08strategy\x18\x02 \x01(\x0e\x32\x17.ringo.v1.RetryStrategy\x12\x30\n\rinitial_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\tmax_delay\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x12\n\nmultiplier\x18\x05 \x01(\x01\x12\x0e\n\x06jitter\x18\x06 \x01(\x01\x12\x19\n\x11\x64\x65\x63rease_priority\x18\x07 \x01(\x08\"\xc6\x01\n\x08TaskSpec\x12\x12\n\nunique_key\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\'\n\x07payload\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\x12\x10\n\x08priority\x18\x04 \x01(\x05\x12+\n\x0cretry_policy\x18\x05 \x01(\x0b\x32\x15.ringo.v1.RetryPolicy\x12\x30\n\x0c\x61vailable_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd4\x04\n\x04Task\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05queue\x18\x02 \x01(\t\x12\x12\n\nunique_key\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\x12\'\n\x07payload\x18\x05 \x01(\x0b\x32\x16.google.protobuf.Value\x12\x10\n\x08priority\x18\x06 \x01(\x05\x12$\n\x06status\x18\x07 \x01(\x0e\x32\x14.ringo.v1.TaskStatus\x12\x0f\n\x07\x61ttempt\x18\x08 \x01(\r\x12\x14\n\x0cmax_attempts\x18\t \x01(\r\x12\x30\n\x0c\x61vailable_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\ncreated_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x63ompleted_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nlast_error\x18\x0e \x01(\t\x12\x1c\n\x14last_error_truncated\x18\x0f \x01(\x08\x12#\n\x08\x61ttempts\x18\x10 \x03(\x0b\x32\x11.ringo.v1.Attempt\x12$\n\x08progress\x18\x11 \x01(\x0b\x32\x12.ringo.v1.Progress\x12*\n\rcurrent_lease\x18\x12 \x01(\x0b\x32\x13.ringo.v1.LeaseInfo\x12\x1a\n\x12\x61ttempts_truncated\x18\x13 \x01(\x08\"\xda\x01\n\x07\x41ttempt\x12\x0e\n\x06number\x18\x01 \x01(\r\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12.\n\nstarted_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x66inished_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07outcome\x18\x05 \x01(\t\x12\r\n\x05\x65rror\x18\x06 \x01(\t\x12\x17\n\x0f\x65rror_truncated\x18\x07 \x01(\x08\x12\x12\n\nhistory_id\x18\x08 \x01(\x04\"k\n\x08Progress\x12\x0f\n\x07\x63urrent\x18\x01 \x01(\x01\x12\r\n\x05total\x18\x02 \x01(\x01\x12\x0f\n\x07message\x18\x03 \x01(\t\x12.\n\nupdated_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"Z\n\tLeaseInfo\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\r\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12)\n\x05until\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"|\n\x05Lease\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x02 \x01(\r\x12\x13\n\x0blease_token\x18\x03 \x01(\t\x12\x11\n\tworker_id\x18\x04 \x01(\t\x12)\n\x05until\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"J\n\nLeasedTask\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\x12\x1e\n\x05lease\x18\x02 \x01(\x0b\x32\x0f.ringo.v1.Lease\"l\n\x0e\x45nqueueRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12 \n\x04task\x18\x02 \x01(\x0b\x32\x12.ringo.v1.TaskSpec\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"O\n\rEnqueueResult\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63reated\x18\x02 \x01(\x08\x12\x1c\n\x04task\x18\x03 \x01(\x0b\x32\x0e.ringo.v1.Task\":\n\x0f\x45nqueueResponse\x12\'\n\x06result\x18\x01 \x01(\x0b\x32\x17.ringo.v1.EnqueueResult\"q\n\x12\x45nqueueManyRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12!\n\x05tasks\x18\x02 \x03(\x0b\x32\x12.ringo.v1.TaskSpec\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"o\n\x13\x45nqueueManyResponse\x12(\n\x07results\x18\x01 \x03(\x0b\x32\x17.ringo.v1.EnqueueResult\x12\x15\n\rcreated_count\x18\x02 \x01(\r\x12\x17\n\x0f\x64uplicate_count\x18\x03 \x01(\r\"z\n\x0eGetTaskRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"/\n\x0fGetTaskResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\xa1\x01\n\x16GetTaskAttemptsRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12\r\n\x05limit\x18\x04 \x01(\r\x12\x0e\n\x06\x63ursor\x18\x05 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"S\n\x17GetTaskAttemptsResponse\x12#\n\x08\x61ttempts\x18\x01 \x03(\x0b\x32\x11.ringo.v1.Attempt\x12\x13\n\x0bnext_cursor\x18\x02 \x01(\t\"g\n\x17GetQueueActivityRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x12\n\ntask_types\x18\x02 \x03(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"5\n\x18GetQueueActivityResponse\x12\x19\n\x11\x61\x63tive_task_count\x18\x01 \x01(\x04\"d\n\x14GetQueueStatsRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x12\n\ntask_types\x18\x02 \x03(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\xbd\x02\n\x15GetQueueStatsResponse\x12\x17\n\x0fscheduled_count\x18\x01 \x01(\x04\x12\x13\n\x0bready_count\x18\x02 \x01(\x04\x12\x14\n\x0cleased_count\x18\x03 \x01(\x04\x12\x17\n\x0fsucceeded_count\x18\x04 \x01(\x04\x12\x12\n\ndead_count\x18\x05 \x01(\x04\x12\x17\n\x0f\x63\x61ncelled_count\x18\x06 \x01(\x04\x12/\n\x0bobserved_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0foldest_ready_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x10last_activity_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"|\n\x10RetryTaskRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"1\n\x11RetryTaskResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\xe2\x01\n\x0c\x43laimRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12\x12\n\ntask_types\x18\x03 \x03(\t\x12\r\n\x05limit\x18\x04 \x01(\r\x12/\n\x0cwait_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0elease_duration\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"4\n\rClaimResponse\x12#\n\x05tasks\x18\x01 \x03(\x0b\x32\x14.ringo.v1.LeasedTask\"A\n\x08LeaseRef\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x02 \x01(\r\x12\x13\n\x0blease_token\x18\x03 \x01(\t\"Z\n\nAckRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\r\n\x0b\x41\x63kResponse\"\xa3\x01\n\x0bNackRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x12\x37\n\x14retry_delay_override\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\",\n\x0cNackResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"l\n\rRejectRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\".\n\x0eRejectResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\x90\x01\n\x12\x45xtendLeaseRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12,\n\textension\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"5\n\x13\x45xtendLeaseResponse\x12\x1e\n\x05lease\x18\x01 \x01(\x0b\x32\x0f.ringo.v1.Lease\"\x96\x01\n\x15ReportProgressRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\x01\x12\r\n\x05total\x18\x03 \x01(\x01\x12\x0f\n\x07message\x18\x04 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\x18\n\x16ReportProgressResponse\"\xc1\x01\n\x12WorkerRegistration\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12\x12\n\ntask_types\x18\x03 \x03(\t\x12\x17\n\x0fmax_concurrency\x18\x04 \x01(\r\x12\x31\n\x0elease_duration\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"Y\n\x0c\x43reditUpdate\x12\x11\n\tavailable\x18\x01 \x01(\r\x12\x1f\n\x12target_concurrency\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\x15\n\x13_target_concurrency\"\x1c\n\x0bWorkerDrain\x12\r\n\x05\x62\x65gin\x18\x01 \x01(\x08\"q\n\x10WorkerRegistered\x12\x11\n\tworker_id\x18\x01 \x01(\t\x12\x17\n\x0fmax_concurrency\x18\x02 \x01(\r\x12\x31\n\x0elease_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\"\x8f\x03\n\x0bWorkRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\x04\x12\x30\n\x08register\x18\x02 \x01(\x0b\x32\x1c.ringo.v1.WorkerRegistrationH\x00\x12(\n\x06\x63redit\x18\x03 \x01(\x0b\x32\x16.ringo.v1.CreditUpdateH\x00\x12#\n\x03\x61\x63k\x18\x04 \x01(\x0b\x32\x14.ringo.v1.AckRequestH\x00\x12%\n\x04nack\x18\x05 \x01(\x0b\x32\x15.ringo.v1.NackRequestH\x00\x12)\n\x06reject\x18\x06 \x01(\x0b\x32\x17.ringo.v1.RejectRequestH\x00\x12\x34\n\x0c\x65xtend_lease\x18\x07 \x01(\x0b\x32\x1c.ringo.v1.ExtendLeaseRequestH\x00\x12\x33\n\x08progress\x18\x08 \x01(\x0b\x32\x1f.ringo.v1.ReportProgressRequestH\x00\x12&\n\x05\x64rain\x18\t \x01(\x0b\x32\x15.ringo.v1.WorkerDrainH\x00\x42\x06\n\x04\x62ody\"F\n\nWorkResult\x12\x12\n\nrequest_id\x18\x01 \x01(\x04\x12$\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x15.ringo.v1.ErrorDetail\"\xc7\x01\n\x0cWorkResponse\x12$\n\x04task\x18\x01 \x01(\x0b\x32\x14.ringo.v1.LeasedTaskH\x00\x12&\n\x06result\x18\x02 \x01(\x0b\x32\x14.ringo.v1.WorkResultH\x00\x12/\n\theartbeat\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x12\x30\n\nregistered\x18\x04 \x01(\x0b\x32\x1a.ringo.v1.WorkerRegisteredH\x00\x42\x06\n\x04\x62ody*\xbf\x01\n\nTaskStatus\x12\x1b\n\x17TASK_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15TASK_STATUS_SCHEDULED\x10\x01\x12\x15\n\x11TASK_STATUS_READY\x10\x02\x12\x16\n\x12TASK_STATUS_LEASED\x10\x03\x12\x19\n\x15TASK_STATUS_SUCCEEDED\x10\x04\x12\x14\n\x10TASK_STATUS_DEAD\x10\x05\x12\x19\n\x15TASK_STATUS_CANCELLED\x10\x06*i\n\rRetryStrategy\x12\x1e\n\x1aRETRY_STRATEGY_UNSPECIFIED\x10\x00\x12\x18\n\x14RETRY_STRATEGY_FIXED\x10\x01\x12\x1e\n\x1aRETRY_STRATEGY_EXPONENTIAL\x10\x02*\xac\x02\n\tErrorCode\x12\x1a\n\x16\x45RROR_CODE_UNSPECIFIED\x10\x00\x12\x1f\n\x1b\x45RROR_CODE_INVALID_ARGUMENT\x10\x01\x12\x18\n\x14\x45RROR_CODE_DUPLICATE\x10\x02\x12\x18\n\x14\x45RROR_CODE_NOT_FOUND\x10\x03\x12\x17\n\x13\x45RROR_CODE_CONFLICT\x10\x04\x12\x19\n\x15\x45RROR_CODE_LEASE_LOST\x10\x05\x12\x1a\n\x16\x45RROR_CODE_UNAVAILABLE\x10\x06\x12 \n\x1c\x45RROR_CODE_DEADLINE_EXCEEDED\x10\x07\x12#\n\x1f\x45RROR_CODE_INCOMPATIBLE_VERSION\x10\x08\x12\x17\n\x13\x45RROR_CODE_INTERNAL\x10\t2\xf7\x08\n\x0cQueueService\x12\x44\n\tNegotiate\x12\x1a.ringo.v1.NegotiateRequest\x1a\x1b.ringo.v1.NegotiateResponse\x12>\n\x07\x45nqueue\x12\x18.ringo.v1.EnqueueRequest\x1a\x19.ringo.v1.EnqueueResponse\x12J\n\x0b\x45nqueueMany\x12\x1c.ringo.v1.EnqueueManyRequest\x1a\x1d.ringo.v1.EnqueueManyResponse\x12>\n\x07GetTask\x12\x18.ringo.v1.GetTaskRequest\x1a\x19.ringo.v1.GetTaskResponse\x12V\n\x0fGetTaskAttempts\x12 .ringo.v1.GetTaskAttemptsRequest\x1a!.ringo.v1.GetTaskAttemptsResponse\x12Y\n\x10GetQueueActivity\x12!.ringo.v1.GetQueueActivityRequest\x1a\".ringo.v1.GetQueueActivityResponse\x12P\n\rGetQueueStats\x12\x1e.ringo.v1.GetQueueStatsRequest\x1a\x1f.ringo.v1.GetQueueStatsResponse\x12\x44\n\tRetryTask\x12\x1a.ringo.v1.RetryTaskRequest\x1a\x1b.ringo.v1.RetryTaskResponse\x12\x38\n\x05\x43laim\x12\x16.ringo.v1.ClaimRequest\x1a\x17.ringo.v1.ClaimResponse\x12\x32\n\x03\x41\x63k\x12\x14.ringo.v1.AckRequest\x1a\x15.ringo.v1.AckResponse\x12\x35\n\x04Nack\x12\x15.ringo.v1.NackRequest\x1a\x16.ringo.v1.NackResponse\x12;\n\x06Reject\x12\x17.ringo.v1.RejectRequest\x1a\x18.ringo.v1.RejectResponse\x12J\n\x0b\x45xtendLease\x12\x1c.ringo.v1.ExtendLeaseRequest\x1a\x1d.ringo.v1.ExtendLeaseResponse\x12S\n\x0eReportProgress\x12\x1f.ringo.v1.ReportProgressRequest\x1a .ringo.v1.ReportProgressResponse\x12\x39\n\x04Work\x12\x15.ringo.v1.WorkRequest\x1a\x16.ringo.v1.WorkResponse(\x01\x30\x01\x12L\n\x0b\x41ttachLocal\x12\x1c.ringo.v1.AttachLocalRequest\x1a\x1d.ringo.v1.AttachLocalResponse0\x01\x42l\n\x16\x64\x65v.ringo.taskqueue.v1B\nQueueProtoP\x01ZDgithub.com/ringo-task-queue/ringo-task-queue/gen/go/ringo/v1;ringov1b\x06proto3')
|
|
31
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,ringo_task_queue/_proto/ringo/v1/queue.proto\x12\x08ringo.v1\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"(\n\x12\x41ttachLocalRequest\x12\x12\n\ngeneration\x18\x01 \x01(\t\")\n\x13\x41ttachLocalResponse\x12\x12\n\ngeneration\x18\x01 \x01(\t\"i\n\x10NegotiateRequest\x12\x10\n\x08sdk_name\x18\x01 \x01(\t\x12\x13\n\x0bsdk_version\x18\x02 \x01(\t\x12\x16\n\x0eprotocol_major\x18\x03 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x04 \x01(\r\"\x88\x01\n\x11NegotiateResponse\x12\x16\n\x0eserver_version\x18\x01 \x01(\t\x12\x16\n\x0eprotocol_major\x18\x02 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x03 \x01(\r\x12\x14\n\x0c\x63\x61pabilities\x18\x04 \x03(\t\x12\x15\n\rsession_token\x18\x05 \x01(\t\"W\n\x0eRequestContext\x12\x16\n\x0eprotocol_major\x18\x01 \x01(\r\x12\x16\n\x0eprotocol_minor\x18\x02 \x01(\r\x12\x15\n\rsession_token\x18\x03 \x01(\t\"\xbd\x01\n\x0b\x45rrorDetail\x12!\n\x04\x63ode\x18\x01 \x01(\x0e\x32\x13.ringo.v1.ErrorCode\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12\x35\n\x08metadata\x18\x04 \x03(\x0b\x32#.ringo.v1.ErrorDetail.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xed\x01\n\x0bRetryPolicy\x12\x14\n\x0cmax_attempts\x18\x01 \x01(\r\x12)\n\x08strategy\x18\x02 \x01(\x0e\x32\x17.ringo.v1.RetryStrategy\x12\x30\n\rinitial_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12,\n\tmax_delay\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x12\n\nmultiplier\x18\x05 \x01(\x01\x12\x0e\n\x06jitter\x18\x06 \x01(\x01\x12\x19\n\x11\x64\x65\x63rease_priority\x18\x07 \x01(\x08\"\xc6\x01\n\x08TaskSpec\x12\x12\n\nunique_key\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\'\n\x07payload\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\x12\x10\n\x08priority\x18\x04 \x01(\x05\x12+\n\x0cretry_policy\x18\x05 \x01(\x0b\x32\x15.ringo.v1.RetryPolicy\x12\x30\n\x0c\x61vailable_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd4\x04\n\x04Task\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05queue\x18\x02 \x01(\t\x12\x12\n\nunique_key\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\x12\'\n\x07payload\x18\x05 \x01(\x0b\x32\x16.google.protobuf.Value\x12\x10\n\x08priority\x18\x06 \x01(\x05\x12$\n\x06status\x18\x07 \x01(\x0e\x32\x14.ringo.v1.TaskStatus\x12\x0f\n\x07\x61ttempt\x18\x08 \x01(\r\x12\x14\n\x0cmax_attempts\x18\t \x01(\r\x12\x30\n\x0c\x61vailable_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\ncreated_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x63ompleted_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nlast_error\x18\x0e \x01(\t\x12\x1c\n\x14last_error_truncated\x18\x0f \x01(\x08\x12#\n\x08\x61ttempts\x18\x10 \x03(\x0b\x32\x11.ringo.v1.Attempt\x12$\n\x08progress\x18\x11 \x01(\x0b\x32\x12.ringo.v1.Progress\x12*\n\rcurrent_lease\x18\x12 \x01(\x0b\x32\x13.ringo.v1.LeaseInfo\x12\x1a\n\x12\x61ttempts_truncated\x18\x13 \x01(\x08\"\xda\x01\n\x07\x41ttempt\x12\x0e\n\x06number\x18\x01 \x01(\r\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12.\n\nstarted_at\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x66inished_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07outcome\x18\x05 \x01(\t\x12\r\n\x05\x65rror\x18\x06 \x01(\t\x12\x17\n\x0f\x65rror_truncated\x18\x07 \x01(\x08\x12\x12\n\nhistory_id\x18\x08 \x01(\x04\"k\n\x08Progress\x12\x0f\n\x07\x63urrent\x18\x01 \x01(\x01\x12\r\n\x05total\x18\x02 \x01(\x01\x12\x0f\n\x07message\x18\x03 \x01(\t\x12.\n\nupdated_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"Z\n\tLeaseInfo\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\r\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12)\n\x05until\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"|\n\x05Lease\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x02 \x01(\r\x12\x13\n\x0blease_token\x18\x03 \x01(\t\x12\x11\n\tworker_id\x18\x04 \x01(\t\x12)\n\x05until\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"J\n\nLeasedTask\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\x12\x1e\n\x05lease\x18\x02 \x01(\x0b\x32\x0f.ringo.v1.Lease\"l\n\x0e\x45nqueueRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12 \n\x04task\x18\x02 \x01(\x0b\x32\x12.ringo.v1.TaskSpec\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"O\n\rEnqueueResult\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63reated\x18\x02 \x01(\x08\x12\x1c\n\x04task\x18\x03 \x01(\x0b\x32\x0e.ringo.v1.Task\":\n\x0f\x45nqueueResponse\x12\'\n\x06result\x18\x01 \x01(\x0b\x32\x17.ringo.v1.EnqueueResult\"q\n\x12\x45nqueueManyRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12!\n\x05tasks\x18\x02 \x03(\x0b\x32\x12.ringo.v1.TaskSpec\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"o\n\x13\x45nqueueManyResponse\x12(\n\x07results\x18\x01 \x03(\x0b\x32\x17.ringo.v1.EnqueueResult\x12\x15\n\rcreated_count\x18\x02 \x01(\r\x12\x17\n\x0f\x64uplicate_count\x18\x03 \x01(\r\"z\n\x0eGetTaskRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"/\n\x0fGetTaskResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\xa1\x01\n\x16GetTaskAttemptsRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12\r\n\x05limit\x18\x04 \x01(\r\x12\x0e\n\x06\x63ursor\x18\x05 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"S\n\x17GetTaskAttemptsResponse\x12#\n\x08\x61ttempts\x18\x01 \x03(\x0b\x32\x11.ringo.v1.Attempt\x12\x13\n\x0bnext_cursor\x18\x02 \x01(\t\"g\n\x17GetQueueActivityRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x12\n\ntask_types\x18\x02 \x03(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"5\n\x18GetQueueActivityResponse\x12\x19\n\x11\x61\x63tive_task_count\x18\x01 \x01(\x04\"d\n\x14GetQueueStatsRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x12\n\ntask_types\x18\x02 \x03(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\xbd\x02\n\x15GetQueueStatsResponse\x12\x17\n\x0fscheduled_count\x18\x01 \x01(\x04\x12\x13\n\x0bready_count\x18\x02 \x01(\x04\x12\x14\n\x0cleased_count\x18\x03 \x01(\x04\x12\x17\n\x0fsucceeded_count\x18\x04 \x01(\x04\x12\x12\n\ndead_count\x18\x05 \x01(\x04\x12\x17\n\x0f\x63\x61ncelled_count\x18\x06 \x01(\x04\x12/\n\x0bobserved_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x33\n\x0foldest_ready_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x34\n\x10last_activity_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"|\n\x10RetryTaskRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\x07task_id\x18\x02 \x01(\tH\x00\x12\x14\n\nunique_key\x18\x03 \x01(\tH\x00\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContextB\x05\n\x03key\"1\n\x11RetryTaskResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\xe2\x01\n\x0c\x43laimRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12\x12\n\ntask_types\x18\x03 \x03(\t\x12\r\n\x05limit\x18\x04 \x01(\r\x12/\n\x0cwait_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0elease_duration\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"4\n\rClaimResponse\x12#\n\x05tasks\x18\x01 \x03(\x0b\x32\x14.ringo.v1.LeasedTask\"A\n\x08LeaseRef\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0f\n\x07\x61ttempt\x18\x02 \x01(\r\x12\x13\n\x0blease_token\x18\x03 \x01(\t\"Z\n\nAckRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\r\n\x0b\x41\x63kResponse\"\xa3\x01\n\x0bNackRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x12\x37\n\x14retry_delay_override\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\",\n\x0cNackResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"l\n\rRejectRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\".\n\x0eRejectResponse\x12\x1c\n\x04task\x18\x01 \x01(\x0b\x32\x0e.ringo.v1.Task\"\x90\x01\n\x12\x45xtendLeaseRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12,\n\textension\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"5\n\x13\x45xtendLeaseResponse\x12\x1e\n\x05lease\x18\x01 \x01(\x0b\x32\x0f.ringo.v1.Lease\"\x96\x01\n\x15ReportProgressRequest\x12!\n\x05lease\x18\x01 \x01(\x0b\x32\x12.ringo.v1.LeaseRef\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\x01\x12\r\n\x05total\x18\x03 \x01(\x01\x12\x0f\n\x07message\x18\x04 \x01(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"\x18\n\x16ReportProgressResponse\"\xde\x01\n\x12WorkerRegistration\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x11\n\tworker_id\x18\x02 \x01(\t\x12\x12\n\ntask_types\x18\x03 \x03(\t\x12\x17\n\x0fmax_concurrency\x18\x04 \x01(\r\x12\x31\n\x0elease_duration\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1b\n\x13ordered_request_ids\x18\x06 \x01(\x08\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"Y\n\x0c\x43reditUpdate\x12\x11\n\tavailable\x18\x01 \x01(\r\x12\x1f\n\x12target_concurrency\x18\x02 \x01(\rH\x00\x88\x01\x01\x42\x15\n\x13_target_concurrency\"\x1c\n\x0bWorkerDrain\x12\r\n\x05\x62\x65gin\x18\x01 \x01(\x08\"\x8e\x01\n\x10WorkerRegistered\x12\x11\n\tworker_id\x18\x01 \x01(\t\x12\x17\n\x0fmax_concurrency\x18\x02 \x01(\r\x12\x31\n\x0elease_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1b\n\x13ordered_request_ids\x18\x04 \x01(\x08\"\x8f\x03\n\x0bWorkRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\x04\x12\x30\n\x08register\x18\x02 \x01(\x0b\x32\x1c.ringo.v1.WorkerRegistrationH\x00\x12(\n\x06\x63redit\x18\x03 \x01(\x0b\x32\x16.ringo.v1.CreditUpdateH\x00\x12#\n\x03\x61\x63k\x18\x04 \x01(\x0b\x32\x14.ringo.v1.AckRequestH\x00\x12%\n\x04nack\x18\x05 \x01(\x0b\x32\x15.ringo.v1.NackRequestH\x00\x12)\n\x06reject\x18\x06 \x01(\x0b\x32\x17.ringo.v1.RejectRequestH\x00\x12\x34\n\x0c\x65xtend_lease\x18\x07 \x01(\x0b\x32\x1c.ringo.v1.ExtendLeaseRequestH\x00\x12\x33\n\x08progress\x18\x08 \x01(\x0b\x32\x1f.ringo.v1.ReportProgressRequestH\x00\x12&\n\x05\x64rain\x18\t \x01(\x0b\x32\x15.ringo.v1.WorkerDrainH\x00\x42\x06\n\x04\x62ody\"F\n\nWorkResult\x12\x12\n\nrequest_id\x18\x01 \x01(\x04\x12$\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x15.ringo.v1.ErrorDetail\"\xc7\x01\n\x0cWorkResponse\x12$\n\x04task\x18\x01 \x01(\x0b\x32\x14.ringo.v1.LeasedTaskH\x00\x12&\n\x06result\x18\x02 \x01(\x0b\x32\x14.ringo.v1.WorkResultH\x00\x12/\n\theartbeat\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x12\x30\n\nregistered\x18\x04 \x01(\x0b\x32\x1a.ringo.v1.WorkerRegisteredH\x00\x42\x06\n\x04\x62ody\"a\n\x11ProbeQueueRequest\x12\r\n\x05queue\x18\x01 \x01(\t\x12\x12\n\ntask_types\x18\x02 \x03(\t\x12)\n\x07\x63ontext\x18\x0f \x01(\x0b\x32\x18.ringo.v1.RequestContext\"0\n\x12ProbeQueueResponse\x12\x1a\n\x12has_eligible_tasks\x18\x01 \x01(\x08*\xbf\x01\n\nTaskStatus\x12\x1b\n\x17TASK_STATUS_UNSPECIFIED\x10\x00\x12\x19\n\x15TASK_STATUS_SCHEDULED\x10\x01\x12\x15\n\x11TASK_STATUS_READY\x10\x02\x12\x16\n\x12TASK_STATUS_LEASED\x10\x03\x12\x19\n\x15TASK_STATUS_SUCCEEDED\x10\x04\x12\x14\n\x10TASK_STATUS_DEAD\x10\x05\x12\x19\n\x15TASK_STATUS_CANCELLED\x10\x06*i\n\rRetryStrategy\x12\x1e\n\x1aRETRY_STRATEGY_UNSPECIFIED\x10\x00\x12\x18\n\x14RETRY_STRATEGY_FIXED\x10\x01\x12\x1e\n\x1aRETRY_STRATEGY_EXPONENTIAL\x10\x02*\xac\x02\n\tErrorCode\x12\x1a\n\x16\x45RROR_CODE_UNSPECIFIED\x10\x00\x12\x1f\n\x1b\x45RROR_CODE_INVALID_ARGUMENT\x10\x01\x12\x18\n\x14\x45RROR_CODE_DUPLICATE\x10\x02\x12\x18\n\x14\x45RROR_CODE_NOT_FOUND\x10\x03\x12\x17\n\x13\x45RROR_CODE_CONFLICT\x10\x04\x12\x19\n\x15\x45RROR_CODE_LEASE_LOST\x10\x05\x12\x1a\n\x16\x45RROR_CODE_UNAVAILABLE\x10\x06\x12 \n\x1c\x45RROR_CODE_DEADLINE_EXCEEDED\x10\x07\x12#\n\x1f\x45RROR_CODE_INCOMPATIBLE_VERSION\x10\x08\x12\x17\n\x13\x45RROR_CODE_INTERNAL\x10\t2\xc0\t\n\x0cQueueService\x12\x44\n\tNegotiate\x12\x1a.ringo.v1.NegotiateRequest\x1a\x1b.ringo.v1.NegotiateResponse\x12>\n\x07\x45nqueue\x12\x18.ringo.v1.EnqueueRequest\x1a\x19.ringo.v1.EnqueueResponse\x12J\n\x0b\x45nqueueMany\x12\x1c.ringo.v1.EnqueueManyRequest\x1a\x1d.ringo.v1.EnqueueManyResponse\x12>\n\x07GetTask\x12\x18.ringo.v1.GetTaskRequest\x1a\x19.ringo.v1.GetTaskResponse\x12V\n\x0fGetTaskAttempts\x12 .ringo.v1.GetTaskAttemptsRequest\x1a!.ringo.v1.GetTaskAttemptsResponse\x12Y\n\x10GetQueueActivity\x12!.ringo.v1.GetQueueActivityRequest\x1a\".ringo.v1.GetQueueActivityResponse\x12P\n\rGetQueueStats\x12\x1e.ringo.v1.GetQueueStatsRequest\x1a\x1f.ringo.v1.GetQueueStatsResponse\x12\x44\n\tRetryTask\x12\x1a.ringo.v1.RetryTaskRequest\x1a\x1b.ringo.v1.RetryTaskResponse\x12\x38\n\x05\x43laim\x12\x16.ringo.v1.ClaimRequest\x1a\x17.ringo.v1.ClaimResponse\x12\x32\n\x03\x41\x63k\x12\x14.ringo.v1.AckRequest\x1a\x15.ringo.v1.AckResponse\x12\x35\n\x04Nack\x12\x15.ringo.v1.NackRequest\x1a\x16.ringo.v1.NackResponse\x12;\n\x06Reject\x12\x17.ringo.v1.RejectRequest\x1a\x18.ringo.v1.RejectResponse\x12J\n\x0b\x45xtendLease\x12\x1c.ringo.v1.ExtendLeaseRequest\x1a\x1d.ringo.v1.ExtendLeaseResponse\x12S\n\x0eReportProgress\x12\x1f.ringo.v1.ReportProgressRequest\x1a .ringo.v1.ReportProgressResponse\x12\x39\n\x04Work\x12\x15.ringo.v1.WorkRequest\x1a\x16.ringo.v1.WorkResponse(\x01\x30\x01\x12L\n\x0b\x41ttachLocal\x12\x1c.ringo.v1.AttachLocalRequest\x1a\x1d.ringo.v1.AttachLocalResponse0\x01\x12G\n\nProbeQueue\x12\x1b.ringo.v1.ProbeQueueRequest\x1a\x1c.ringo.v1.ProbeQueueResponseBl\n\x16\x64\x65v.ringo.taskqueue.v1B\nQueueProtoP\x01ZDgithub.com/ringo-task-queue/ringo-task-queue/gen/go/ringo/v1;ringov1b\x06proto3')
|
|
32
32
|
|
|
33
33
|
_globals = globals()
|
|
34
34
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -38,12 +38,12 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
38
38
|
_globals['DESCRIPTOR']._serialized_options = b'\n\026dev.ringo.taskqueue.v1B\nQueueProtoP\001ZDgithub.com/ringo-task-queue/ringo-task-queue/gen/go/ringo/v1;ringov1'
|
|
39
39
|
_globals['_ERRORDETAIL_METADATAENTRY']._loaded_options = None
|
|
40
40
|
_globals['_ERRORDETAIL_METADATAENTRY']._serialized_options = b'8\001'
|
|
41
|
-
_globals['_TASKSTATUS']._serialized_start=
|
|
42
|
-
_globals['_TASKSTATUS']._serialized_end=
|
|
43
|
-
_globals['_RETRYSTRATEGY']._serialized_start=
|
|
44
|
-
_globals['_RETRYSTRATEGY']._serialized_end=
|
|
45
|
-
_globals['_ERRORCODE']._serialized_start=
|
|
46
|
-
_globals['_ERRORCODE']._serialized_end=
|
|
41
|
+
_globals['_TASKSTATUS']._serialized_start=6614
|
|
42
|
+
_globals['_TASKSTATUS']._serialized_end=6805
|
|
43
|
+
_globals['_RETRYSTRATEGY']._serialized_start=6807
|
|
44
|
+
_globals['_RETRYSTRATEGY']._serialized_end=6912
|
|
45
|
+
_globals['_ERRORCODE']._serialized_start=6915
|
|
46
|
+
_globals['_ERRORCODE']._serialized_end=7215
|
|
47
47
|
_globals['_ATTACHLOCALREQUEST']._serialized_start=153
|
|
48
48
|
_globals['_ATTACHLOCALREQUEST']._serialized_end=193
|
|
49
49
|
_globals['_ATTACHLOCALRESPONSE']._serialized_start=195
|
|
@@ -131,19 +131,23 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
131
131
|
_globals['_REPORTPROGRESSRESPONSE']._serialized_start=5271
|
|
132
132
|
_globals['_REPORTPROGRESSRESPONSE']._serialized_end=5295
|
|
133
133
|
_globals['_WORKERREGISTRATION']._serialized_start=5298
|
|
134
|
-
_globals['_WORKERREGISTRATION']._serialized_end=
|
|
135
|
-
_globals['_CREDITUPDATE']._serialized_start=
|
|
136
|
-
_globals['_CREDITUPDATE']._serialized_end=
|
|
137
|
-
_globals['_WORKERDRAIN']._serialized_start=
|
|
138
|
-
_globals['_WORKERDRAIN']._serialized_end=
|
|
139
|
-
_globals['_WORKERREGISTERED']._serialized_start=
|
|
140
|
-
_globals['_WORKERREGISTERED']._serialized_end=
|
|
141
|
-
_globals['_WORKREQUEST']._serialized_start=
|
|
142
|
-
_globals['_WORKREQUEST']._serialized_end=
|
|
143
|
-
_globals['_WORKRESULT']._serialized_start=
|
|
144
|
-
_globals['_WORKRESULT']._serialized_end=
|
|
145
|
-
_globals['_WORKRESPONSE']._serialized_start=
|
|
146
|
-
_globals['_WORKRESPONSE']._serialized_end=
|
|
147
|
-
_globals['
|
|
148
|
-
_globals['
|
|
134
|
+
_globals['_WORKERREGISTRATION']._serialized_end=5520
|
|
135
|
+
_globals['_CREDITUPDATE']._serialized_start=5522
|
|
136
|
+
_globals['_CREDITUPDATE']._serialized_end=5611
|
|
137
|
+
_globals['_WORKERDRAIN']._serialized_start=5613
|
|
138
|
+
_globals['_WORKERDRAIN']._serialized_end=5641
|
|
139
|
+
_globals['_WORKERREGISTERED']._serialized_start=5644
|
|
140
|
+
_globals['_WORKERREGISTERED']._serialized_end=5786
|
|
141
|
+
_globals['_WORKREQUEST']._serialized_start=5789
|
|
142
|
+
_globals['_WORKREQUEST']._serialized_end=6188
|
|
143
|
+
_globals['_WORKRESULT']._serialized_start=6190
|
|
144
|
+
_globals['_WORKRESULT']._serialized_end=6260
|
|
145
|
+
_globals['_WORKRESPONSE']._serialized_start=6263
|
|
146
|
+
_globals['_WORKRESPONSE']._serialized_end=6462
|
|
147
|
+
_globals['_PROBEQUEUEREQUEST']._serialized_start=6464
|
|
148
|
+
_globals['_PROBEQUEUEREQUEST']._serialized_end=6561
|
|
149
|
+
_globals['_PROBEQUEUERESPONSE']._serialized_start=6563
|
|
150
|
+
_globals['_PROBEQUEUERESPONSE']._serialized_end=6611
|
|
151
|
+
_globals['_QUEUESERVICE']._serialized_start=7218
|
|
152
|
+
_globals['_QUEUESERVICE']._serialized_end=8434
|
|
149
153
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -116,6 +116,11 @@ class QueueServiceStub(object):
|
|
|
116
116
|
request_serializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.AttachLocalRequest.SerializeToString,
|
|
117
117
|
response_deserializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.AttachLocalResponse.FromString,
|
|
118
118
|
_registered_method=True)
|
|
119
|
+
self.ProbeQueue = channel.unary_unary(
|
|
120
|
+
'/ringo.v1.QueueService/ProbeQueue',
|
|
121
|
+
request_serializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueRequest.SerializeToString,
|
|
122
|
+
response_deserializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueResponse.FromString,
|
|
123
|
+
_registered_method=True)
|
|
119
124
|
|
|
120
125
|
|
|
121
126
|
class QueueServiceServicer(object):
|
|
@@ -224,6 +229,14 @@ class QueueServiceServicer(object):
|
|
|
224
229
|
context.set_details('Method not implemented!')
|
|
225
230
|
raise NotImplementedError('Method not implemented!')
|
|
226
231
|
|
|
232
|
+
def ProbeQueue(self, request, context):
|
|
233
|
+
"""Protocol minor 7: read-only existence of currently eligible queue/type work.
|
|
234
|
+
This neither reserves work nor guarantees dispatch to a particular Worker.
|
|
235
|
+
"""
|
|
236
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
237
|
+
context.set_details('Method not implemented!')
|
|
238
|
+
raise NotImplementedError('Method not implemented!')
|
|
239
|
+
|
|
227
240
|
|
|
228
241
|
def add_QueueServiceServicer_to_server(servicer, server):
|
|
229
242
|
rpc_method_handlers = {
|
|
@@ -307,6 +320,11 @@ def add_QueueServiceServicer_to_server(servicer, server):
|
|
|
307
320
|
request_deserializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.AttachLocalRequest.FromString,
|
|
308
321
|
response_serializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.AttachLocalResponse.SerializeToString,
|
|
309
322
|
),
|
|
323
|
+
'ProbeQueue': grpc.unary_unary_rpc_method_handler(
|
|
324
|
+
servicer.ProbeQueue,
|
|
325
|
+
request_deserializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueRequest.FromString,
|
|
326
|
+
response_serializer=ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueResponse.SerializeToString,
|
|
327
|
+
),
|
|
310
328
|
}
|
|
311
329
|
generic_handler = grpc.method_handlers_generic_handler(
|
|
312
330
|
'ringo.v1.QueueService', rpc_method_handlers)
|
|
@@ -750,3 +768,30 @@ class QueueService(object):
|
|
|
750
768
|
timeout,
|
|
751
769
|
metadata,
|
|
752
770
|
_registered_method=True)
|
|
771
|
+
|
|
772
|
+
@staticmethod
|
|
773
|
+
def ProbeQueue(request,
|
|
774
|
+
target,
|
|
775
|
+
options=(),
|
|
776
|
+
channel_credentials=None,
|
|
777
|
+
call_credentials=None,
|
|
778
|
+
insecure=False,
|
|
779
|
+
compression=None,
|
|
780
|
+
wait_for_ready=None,
|
|
781
|
+
timeout=None,
|
|
782
|
+
metadata=None):
|
|
783
|
+
return grpc.experimental.unary_unary(
|
|
784
|
+
request,
|
|
785
|
+
target,
|
|
786
|
+
'/ringo.v1.QueueService/ProbeQueue',
|
|
787
|
+
ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueRequest.SerializeToString,
|
|
788
|
+
ringo__task__queue_dot___proto_dot_ringo_dot_v1_dot_queue__pb2.ProbeQueueResponse.FromString,
|
|
789
|
+
options,
|
|
790
|
+
channel_credentials,
|
|
791
|
+
insecure,
|
|
792
|
+
call_credentials,
|
|
793
|
+
compression,
|
|
794
|
+
wait_for_ready,
|
|
795
|
+
timeout,
|
|
796
|
+
metadata,
|
|
797
|
+
_registered_method=True)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Private subprocess bootstrap. Use the public ``supervise`` function."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import inspect
|
|
7
|
+
import os
|
|
8
|
+
import socket
|
|
9
|
+
import sys
|
|
10
|
+
import traceback
|
|
11
|
+
|
|
12
|
+
from ._supervisor_ipc import Channel
|
|
13
|
+
from ._supervisor_policy import SupervisorPolicy, TaskTimeouts
|
|
14
|
+
from ._supervisor_runtime import ChildRuntime
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _load(entrypoint: str):
|
|
18
|
+
module_name, attribute = entrypoint.split(":", 1)
|
|
19
|
+
result = importlib.import_module(module_name)
|
|
20
|
+
for name in attribute.split("."):
|
|
21
|
+
result = getattr(result, name)
|
|
22
|
+
if not callable(result):
|
|
23
|
+
raise TypeError("supervisor entrypoint must be callable")
|
|
24
|
+
inspect.signature(result).bind()
|
|
25
|
+
return result
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def main() -> int:
|
|
29
|
+
if len(sys.argv) != 2:
|
|
30
|
+
print("This is a private supervisor bootstrap.", file=sys.stderr)
|
|
31
|
+
return 78
|
|
32
|
+
# Never pass the local channel capability on a command line or leave it in
|
|
33
|
+
# the environment inherited by browsers/application subprocesses.
|
|
34
|
+
port = int(os.environ.pop("RINGO_SUPERVISOR_PORT"))
|
|
35
|
+
token = os.environ.pop("RINGO_SUPERVISOR_TOKEN")
|
|
36
|
+
generation = os.environ.pop("RINGO_SUPERVISOR_GENERATION")
|
|
37
|
+
connection = socket.create_connection(("127.0.0.1", port), timeout=30)
|
|
38
|
+
connection.settimeout(None)
|
|
39
|
+
channel = Channel(connection)
|
|
40
|
+
channel.send({"kind": "hello", "token": token, "generation": generation})
|
|
41
|
+
config = channel.receive(timeout=30)
|
|
42
|
+
if (
|
|
43
|
+
config is None
|
|
44
|
+
or config.get("kind") != "configure"
|
|
45
|
+
or config.get("generation") != generation
|
|
46
|
+
):
|
|
47
|
+
channel.close()
|
|
48
|
+
return 78
|
|
49
|
+
# The parent has assigned the Job before allowing *any application import*.
|
|
50
|
+
# Only shared-local's explicit launch path is allowed to break away.
|
|
51
|
+
if config.get("windows_job"):
|
|
52
|
+
os.environ["RINGO_SUPERVISOR_JOB"] = "1"
|
|
53
|
+
else:
|
|
54
|
+
os.environ.pop("RINGO_SUPERVISOR_JOB", None)
|
|
55
|
+
runtime = ChildRuntime(
|
|
56
|
+
channel,
|
|
57
|
+
SupervisorPolicy._from_wire(config["policy"]),
|
|
58
|
+
TaskTimeouts._from_wire(config["task_timeouts"]),
|
|
59
|
+
)
|
|
60
|
+
runtime.start()
|
|
61
|
+
ready = False
|
|
62
|
+
try:
|
|
63
|
+
try:
|
|
64
|
+
function = _load(sys.argv[1])
|
|
65
|
+
except Exception: # noqa: BLE001 - Arbitrary application imports fail closed.
|
|
66
|
+
traceback.print_exc()
|
|
67
|
+
channel.send({"kind": "fatal", "reason": "invalid_entrypoint"})
|
|
68
|
+
return 78
|
|
69
|
+
channel.send({"kind": "ready"})
|
|
70
|
+
ready = True
|
|
71
|
+
return runtime.invoke(function)
|
|
72
|
+
except SystemExit as exc:
|
|
73
|
+
if not ready:
|
|
74
|
+
channel.send({"kind": "fatal", "reason": "entrypoint_import_exited"})
|
|
75
|
+
return 78
|
|
76
|
+
code = exc.code if isinstance(exc.code, int) else (0 if exc.code is None else 1)
|
|
77
|
+
channel.send({"kind": "entrypoint_done", "exit_code": code})
|
|
78
|
+
return code
|
|
79
|
+
except BaseException: # noqa: BLE001 - Final subprocess/application boundary.
|
|
80
|
+
traceback.print_exc()
|
|
81
|
+
try:
|
|
82
|
+
channel.send({"kind": "entrypoint_failed"})
|
|
83
|
+
except OSError:
|
|
84
|
+
pass
|
|
85
|
+
return 1
|
|
86
|
+
finally:
|
|
87
|
+
runtime.close()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Private, bounded same-host supervision channel (not a queue protocol)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import select
|
|
7
|
+
import socket
|
|
8
|
+
import threading
|
|
9
|
+
import time
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
_MAX_FRAME = 256 * 1024
|
|
13
|
+
HEALTH_INTERVAL = 1.0
|
|
14
|
+
_READ_POLL = 0.2
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Channel:
|
|
18
|
+
def __init__(self, connection: socket.socket) -> None:
|
|
19
|
+
self.socket = connection
|
|
20
|
+
self._buffer = bytearray()
|
|
21
|
+
self._write_lock = threading.Lock()
|
|
22
|
+
self._closed = threading.Event()
|
|
23
|
+
|
|
24
|
+
def send(self, message: dict[str, Any]) -> None:
|
|
25
|
+
data = (
|
|
26
|
+
json.dumps(message, separators=(",", ":"), allow_nan=False).encode("utf-8")
|
|
27
|
+
+ b"\n"
|
|
28
|
+
)
|
|
29
|
+
if len(data) > _MAX_FRAME:
|
|
30
|
+
raise ValueError("supervisor IPC frame is too large")
|
|
31
|
+
with self._write_lock:
|
|
32
|
+
if self._closed.is_set():
|
|
33
|
+
raise OSError("supervisor IPC channel is closed")
|
|
34
|
+
self.socket.sendall(data)
|
|
35
|
+
|
|
36
|
+
def receive(self, *, timeout: float | None = None) -> dict[str, Any] | None:
|
|
37
|
+
# Exactly one reader owns this buffer. Avoid socket.makefile(): closing
|
|
38
|
+
# its BufferedReader from another thread can wait forever for readline's
|
|
39
|
+
# lock on Windows, even after socket.shutdown(). A raw socket has no
|
|
40
|
+
# hidden file reference/lock, and polling makes local close bounded.
|
|
41
|
+
deadline = None if timeout is None else time.monotonic() + timeout
|
|
42
|
+
while not self._closed.is_set():
|
|
43
|
+
newline = self._buffer.find(b"\n")
|
|
44
|
+
if newline >= 0:
|
|
45
|
+
if newline + 1 > _MAX_FRAME:
|
|
46
|
+
raise ValueError("invalid supervisor IPC frame length")
|
|
47
|
+
data = bytes(self._buffer[:newline])
|
|
48
|
+
del self._buffer[: newline + 1]
|
|
49
|
+
value = json.loads(data)
|
|
50
|
+
if not isinstance(value, dict):
|
|
51
|
+
# The value is malformed wire data, not a Python argument.
|
|
52
|
+
raise ValueError("supervisor IPC frame must be an object")
|
|
53
|
+
return value
|
|
54
|
+
if len(self._buffer) >= _MAX_FRAME:
|
|
55
|
+
raise ValueError("invalid supervisor IPC frame length")
|
|
56
|
+
wait = _READ_POLL
|
|
57
|
+
if deadline is not None:
|
|
58
|
+
remaining = deadline - time.monotonic()
|
|
59
|
+
if remaining <= 0:
|
|
60
|
+
raise TimeoutError("supervisor IPC receive timed out")
|
|
61
|
+
wait = min(wait, remaining)
|
|
62
|
+
readable, _, _ = select.select([self.socket], [], [], wait)
|
|
63
|
+
if not readable:
|
|
64
|
+
continue
|
|
65
|
+
data = self.socket.recv(min(8192, _MAX_FRAME - len(self._buffer)))
|
|
66
|
+
if not data:
|
|
67
|
+
if self._buffer:
|
|
68
|
+
raise ValueError("incomplete supervisor IPC frame")
|
|
69
|
+
return None
|
|
70
|
+
self._buffer.extend(data)
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
def close(self) -> None:
|
|
74
|
+
if self._closed.is_set():
|
|
75
|
+
return
|
|
76
|
+
self._closed.set()
|
|
77
|
+
try:
|
|
78
|
+
self.socket.shutdown(socket.SHUT_RDWR)
|
|
79
|
+
except OSError:
|
|
80
|
+
pass
|
|
81
|
+
self.socket.close()
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""Validated, immutable configuration for opt-in process supervision."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
# Declarative policy validation consistently raises ValueError for bad inputs.
|
|
6
|
+
# ruff: noqa: TRY004
|
|
7
|
+
import math
|
|
8
|
+
from collections.abc import Mapping
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from datetime import timedelta
|
|
11
|
+
from types import MappingProxyType
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _seconds(value: timedelta | None, name: str, *, zero: bool = False) -> float | None:
|
|
16
|
+
if value is None:
|
|
17
|
+
return None
|
|
18
|
+
if not isinstance(value, timedelta):
|
|
19
|
+
raise ValueError(f"{name} must be a timedelta or None")
|
|
20
|
+
seconds = value.total_seconds()
|
|
21
|
+
if not math.isfinite(seconds) or seconds < 0 or (seconds == 0 and not zero):
|
|
22
|
+
raise ValueError(f"{name} must be {'nonnegative' if zero else 'positive'}")
|
|
23
|
+
return seconds
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class TaskTimeouts:
|
|
28
|
+
"""Business execution budgets, excluding queueing and terminal receipts.
|
|
29
|
+
|
|
30
|
+
``by_type`` overrides only ``default``; an explicit ``None`` disables that
|
|
31
|
+
type's execution budget. A Worker-provided object replaces the inherited
|
|
32
|
+
object in full. Progress monitoring is opt-in and arms only after a real
|
|
33
|
+
application progress mark; lease renewal is never business progress.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
default: timedelta | None = None
|
|
37
|
+
by_type: Mapping[str, timedelta | None] = field(default_factory=dict)
|
|
38
|
+
progress_timeout: timedelta | None = None
|
|
39
|
+
cancel_grace: timedelta = timedelta(seconds=5)
|
|
40
|
+
|
|
41
|
+
def __post_init__(self) -> None:
|
|
42
|
+
_seconds(self.default, "default")
|
|
43
|
+
_seconds(self.progress_timeout, "progress_timeout")
|
|
44
|
+
_seconds(self.cancel_grace, "cancel_grace", zero=True)
|
|
45
|
+
if self.cancel_grace is None:
|
|
46
|
+
raise ValueError("cancel_grace must be a timedelta")
|
|
47
|
+
if not isinstance(self.by_type, Mapping):
|
|
48
|
+
raise ValueError("by_type must be a mapping")
|
|
49
|
+
values = dict(self.by_type)
|
|
50
|
+
for key, value in values.items():
|
|
51
|
+
if not isinstance(key, str) or not key:
|
|
52
|
+
raise ValueError("by_type keys must be nonempty task-type strings")
|
|
53
|
+
_seconds(value, f"by_type[{key!r}]")
|
|
54
|
+
object.__setattr__(self, "by_type", MappingProxyType(values))
|
|
55
|
+
|
|
56
|
+
def for_type(self, task_type: str) -> timedelta | None:
|
|
57
|
+
return self.by_type.get(task_type, self.default)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def enabled(self) -> bool:
|
|
61
|
+
return (
|
|
62
|
+
self.default is not None
|
|
63
|
+
or any(value is not None for value in self.by_type.values())
|
|
64
|
+
or self.progress_timeout is not None
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def _to_wire(self) -> dict:
|
|
68
|
+
return {
|
|
69
|
+
"default": _seconds(self.default, "default"),
|
|
70
|
+
"by_type": {
|
|
71
|
+
key: _seconds(value, key) for key, value in self.by_type.items()
|
|
72
|
+
},
|
|
73
|
+
"progress_timeout": _seconds(self.progress_timeout, "progress_timeout"),
|
|
74
|
+
"cancel_grace": _seconds(self.cancel_grace, "cancel_grace", zero=True),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def _from_wire(cls, value: dict) -> TaskTimeouts:
|
|
79
|
+
def duration(seconds):
|
|
80
|
+
return None if seconds is None else timedelta(seconds=seconds)
|
|
81
|
+
|
|
82
|
+
return cls(
|
|
83
|
+
default=duration(value["default"]),
|
|
84
|
+
by_type={
|
|
85
|
+
key: duration(seconds) for key, seconds in value["by_type"].items()
|
|
86
|
+
},
|
|
87
|
+
progress_timeout=duration(value["progress_timeout"]),
|
|
88
|
+
cancel_grace=timedelta(seconds=value["cancel_grace"]),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True)
|
|
93
|
+
class SupervisorPolicy:
|
|
94
|
+
"""Process policy; destructive resource/time thresholds are opt-in.
|
|
95
|
+
|
|
96
|
+
RSS is a sampled, approximate sum for the owned process tree, not a kernel
|
|
97
|
+
hard allocation limit. No-start detection is heuristic under competing
|
|
98
|
+
consumers, so it only warns unless ``restart_on_stall`` is explicit.
|
|
99
|
+
Planned recycling neither consumes nor clears the fault-restart budget.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
recycle_after: timedelta | None = None
|
|
103
|
+
soft_rss_bytes: int | None = None
|
|
104
|
+
max_rss_bytes: int | None = None
|
|
105
|
+
rss_grace: timedelta = timedelta(seconds=30)
|
|
106
|
+
shutdown_grace: timedelta = timedelta(seconds=30)
|
|
107
|
+
startup_timeout: timedelta = timedelta(seconds=30)
|
|
108
|
+
heartbeat_timeout: timedelta | None = None
|
|
109
|
+
no_start_timeout: timedelta | None = None
|
|
110
|
+
restart_on_stall: bool = False
|
|
111
|
+
max_restarts: int = 5
|
|
112
|
+
restart_window: timedelta = timedelta(minutes=10)
|
|
113
|
+
|
|
114
|
+
def __post_init__(self) -> None:
|
|
115
|
+
for name in ("recycle_after", "heartbeat_timeout", "no_start_timeout"):
|
|
116
|
+
_seconds(getattr(self, name), name)
|
|
117
|
+
for name in (
|
|
118
|
+
"rss_grace",
|
|
119
|
+
"shutdown_grace",
|
|
120
|
+
"startup_timeout",
|
|
121
|
+
"restart_window",
|
|
122
|
+
):
|
|
123
|
+
value = getattr(self, name)
|
|
124
|
+
if value is None:
|
|
125
|
+
raise ValueError(f"{name} must be a timedelta")
|
|
126
|
+
_seconds(value, name, zero=name in ("rss_grace", "shutdown_grace"))
|
|
127
|
+
for name in ("soft_rss_bytes", "max_rss_bytes"):
|
|
128
|
+
value = getattr(self, name)
|
|
129
|
+
if value is not None and (
|
|
130
|
+
isinstance(value, bool) or not isinstance(value, int) or value <= 0
|
|
131
|
+
):
|
|
132
|
+
raise ValueError(f"{name} must be a positive integer or None")
|
|
133
|
+
if (
|
|
134
|
+
self.soft_rss_bytes is not None
|
|
135
|
+
and self.max_rss_bytes is not None
|
|
136
|
+
and self.soft_rss_bytes >= self.max_rss_bytes
|
|
137
|
+
):
|
|
138
|
+
raise ValueError("soft_rss_bytes must be smaller than max_rss_bytes")
|
|
139
|
+
if not isinstance(self.restart_on_stall, bool):
|
|
140
|
+
raise ValueError("restart_on_stall must be a boolean")
|
|
141
|
+
if self.restart_on_stall and self.no_start_timeout is None:
|
|
142
|
+
raise ValueError("restart_on_stall requires no_start_timeout")
|
|
143
|
+
if (
|
|
144
|
+
isinstance(self.max_restarts, bool)
|
|
145
|
+
or not isinstance(self.max_restarts, int)
|
|
146
|
+
or self.max_restarts < 0
|
|
147
|
+
):
|
|
148
|
+
raise ValueError("max_restarts must be a nonnegative integer")
|
|
149
|
+
|
|
150
|
+
def _to_wire(self) -> dict:
|
|
151
|
+
return {
|
|
152
|
+
"recycle_after": _seconds(self.recycle_after, "recycle_after"),
|
|
153
|
+
"soft_rss_bytes": self.soft_rss_bytes,
|
|
154
|
+
"max_rss_bytes": self.max_rss_bytes,
|
|
155
|
+
"rss_grace": self.rss_grace.total_seconds(),
|
|
156
|
+
"shutdown_grace": self.shutdown_grace.total_seconds(),
|
|
157
|
+
"startup_timeout": self.startup_timeout.total_seconds(),
|
|
158
|
+
"heartbeat_timeout": _seconds(self.heartbeat_timeout, "heartbeat_timeout"),
|
|
159
|
+
"no_start_timeout": _seconds(self.no_start_timeout, "no_start_timeout"),
|
|
160
|
+
"restart_on_stall": self.restart_on_stall,
|
|
161
|
+
"max_restarts": self.max_restarts,
|
|
162
|
+
"restart_window": self.restart_window.total_seconds(),
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def _from_wire(cls, value: dict) -> SupervisorPolicy:
|
|
167
|
+
duration_names = {
|
|
168
|
+
"recycle_after",
|
|
169
|
+
"rss_grace",
|
|
170
|
+
"shutdown_grace",
|
|
171
|
+
"startup_timeout",
|
|
172
|
+
"heartbeat_timeout",
|
|
173
|
+
"no_start_timeout",
|
|
174
|
+
"restart_window",
|
|
175
|
+
}
|
|
176
|
+
arguments: dict[str, Any] = {
|
|
177
|
+
key: (None if item is None else timedelta(seconds=item))
|
|
178
|
+
if key in duration_names
|
|
179
|
+
else item
|
|
180
|
+
for key, item in value.items()
|
|
181
|
+
}
|
|
182
|
+
return cls(**arguments)
|