| Line | Text | Actions |
|---|
| 1 | from __future__ import annotations | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 2 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 3 | import argparse | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 4 | import datetime as dt | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 5 | import hashlib | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 6 | import json | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 7 | import time | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 8 | from dataclasses import dataclass, field | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 9 | from typing import Dict, List, Tuple | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 10 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 11 | REVISION = "20260902-01-SCHEDV2-SHADOW" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 12 | TERMINAL = {"done", "error", "cancelled", "expired", "superseded"} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 13 | COALESCABLE = {"health", "status", "job_status", "jobs", "recent", "git_status"} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 14 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 15 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 16 | def utc_now() -> dt.datetime: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 17 | return dt.datetime.now(dt.timezone.utc) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 18 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 19 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 20 | @dataclass | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 21 | class Client: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 22 | client_id: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 23 | weight: int = 1 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 24 | max_inflight: int = 1 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 25 | inflight: int = 0 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 26 | last_served_tick: int = 0 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 27 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 28 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 29 | @dataclass | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 30 | class Command: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 31 | command_id: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 32 | client_id: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 33 | seq: int | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 34 | created_at: dt.datetime | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 35 | priority: int = 50 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 36 | resource_keys: Tuple[str, ...] = field(default_factory=tuple) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 37 | action: str = "health" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 38 | payload_json: str = "{}" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 39 | status: str = "pending" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 40 | ttl_seconds: int = 300 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 41 | coalesce_key: str = "" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 42 | supersedes_command_id: str = "" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 43 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 44 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 45 | @dataclass | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 46 | class Lock: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 47 | resource_key: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 48 | command_id: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 49 | client_id: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 50 | fence_token: str | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 51 | lease_until: dt.datetime | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 52 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 53 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 54 | class Scheduler: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 55 | def __init__(self, clients: Dict[str, Client], lease_seconds: int = 60, aging_seconds: int = 30): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 56 | self.clients = clients | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 57 | self.lease_seconds = lease_seconds | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 58 | self.aging_seconds = aging_seconds | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 59 | self.tick = 0 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 60 | self.locks: Dict[str, Lock] = {} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 61 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 62 | def expire_and_coalesce(self, cmds: List[Command], now: dt.datetime | None = None) -> None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 63 | now = now or utc_now() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 64 | by_id = {c.command_id: c for c in cmds} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 65 | latest: Dict[Tuple[str, str], Command] = {} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 66 | for c in cmds: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 67 | if c.status in TERMINAL: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 68 | continue | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 69 | if c.ttl_seconds and (now - c.created_at).total_seconds() > c.ttl_seconds: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 70 | c.status = "expired" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 71 | continue | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 72 | if c.supersedes_command_id: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 73 | superseded = by_id.get(c.supersedes_command_id) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 74 | if superseded and superseded.status == "pending": | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 75 | superseded.status = "superseded" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 76 | if c.action in COALESCABLE and c.coalesce_key: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 77 | key = (c.client_id, c.coalesce_key) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 78 | prev = latest.get(key) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 79 | if prev is None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 80 | latest[key] = c | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 81 | elif (c.seq, c.created_at) > (prev.seq, prev.created_at): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 82 | prev.status = "superseded" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 83 | latest[key] = c | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 84 | else: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 85 | c.status = "superseded" | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 86 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 87 | def resources_free(self, c: Command, now: dt.datetime) -> bool: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 88 | for resource in c.resource_keys: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 89 | lock = self.locks.get(resource) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 90 | if lock and lock.lease_until > now and lock.command_id != c.command_id: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 91 | return False | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 92 | return True | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 93 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 94 | def effective_priority(self, c: Command, now: dt.datetime) -> int: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 95 | age = max(0.0, (now - c.created_at).total_seconds()) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 96 | return c.priority + int(age / self.aging_seconds) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 97 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 98 | def choose(self, cmds: List[Command], now: dt.datetime | None = None) -> Command | None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 99 | now = now or utc_now() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 100 | self.tick += 1 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 101 | self.expire_and_coalesce(cmds, now) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 102 | by_client: Dict[str, List[Command]] = {} | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 103 | for c in cmds: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 104 | if c.status != "pending": | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 105 | continue | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 106 | client = self.clients.get(c.client_id) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 107 | if client is None or client.inflight >= client.max_inflight: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 108 | continue | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 109 | if not self.resources_free(c, now): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 110 | continue | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 111 | by_client.setdefault(c.client_id, []).append(c) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 112 | if not by_client: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 113 | return None | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 114 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 115 | candidates = [] | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 116 | for client_id, arr in by_client.items(): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 117 | client = self.clients[client_id] | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 118 | best = max(arr, key=lambda c: (self.effective_priority(c, now), -c.seq)) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 119 | fairness_age = self.tick - client.last_served_tick | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 120 | score = (self.effective_priority(best, now), fairness_age * max(1, client.weight)) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 121 | candidates.append((score, client_id, best)) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 122 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 123 | _, client_id, chosen = max(candidates, key=lambda item: (item[0][0], item[0][1])) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 124 | self.clients[client_id].last_served_tick = self.tick | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 125 | return chosen | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 126 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 127 | def acquire(self, c: Command, now: dt.datetime | None = None) -> Tuple[str, dt.datetime]: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 128 | now = now or utc_now() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 129 | if not self.resources_free(c, now): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 130 | raise RuntimeError("resource_locked") | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 131 | token = hashlib.sha256( | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 132 | f"{c.command_id}|{c.client_id}|{time.time_ns()}".encode() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 133 | ).hexdigest()[:16] | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 134 | lease_until = now + dt.timedelta(seconds=self.lease_seconds) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 135 | for resource in c.resource_keys: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 136 | self.locks[resource] = Lock(resource, c.command_id, c.client_id, token, lease_until) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 137 | self.clients[c.client_id].inflight += 1 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 138 | return token, lease_until | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 139 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 140 | def release(self, command_id: str, client_id: str, fence_token: str) -> None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 141 | for resource, lock in list(self.locks.items()): | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 142 | if lock.command_id == command_id and lock.fence_token == fence_token: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 143 | self.locks.pop(resource, None) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 144 | client = self.clients.get(client_id) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 145 | if client: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 146 | client.inflight = max(0, client.inflight - 1) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 147 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 148 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 149 | def self_test() -> None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 150 | now = utc_now() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 151 | clients = { | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 152 | "chatgpt-main": Client("chatgpt-main", weight=2, max_inflight=2), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 153 | "chatgpt-work": Client("chatgpt-work", weight=1, max_inflight=1), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 154 | "codex": Client("codex", weight=1, max_inflight=2), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 155 | } | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 156 | scheduler = Scheduler(clients, lease_seconds=60, aging_seconds=10) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 157 | cmds = [ | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 158 | Command("a1", "chatgpt-main", 1, now - dt.timedelta(seconds=5), 50, ("apps-script",), "health", coalesce_key="status"), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 159 | Command("a2", "chatgpt-main", 2, now, 50, ("apps-script",), "health", coalesce_key="status"), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 160 | Command("b1", "chatgpt-work", 1, now, 100, ("android-build",), "health"), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 161 | Command("c1", "codex", 1, now, 20, ("apps-script",), "job_status", ttl_seconds=1), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 162 | Command("c2", "codex", 2, now - dt.timedelta(seconds=20), 20, ("file:project/x",), "git_status", ttl_seconds=5), | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 163 | ] | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 164 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 165 | scheduler.expire_and_coalesce(cmds, now) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 166 | assert cmds[0].status == "superseded", cmds[0].status | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 167 | assert cmds[4].status == "expired", cmds[4].status | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 168 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 169 | first = scheduler.choose(cmds, now) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 170 | assert first and first.command_id == "b1", first | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 171 | token, _ = scheduler.acquire(first, now) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 172 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 173 | second = scheduler.choose(cmds, now) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 174 | assert second and second.command_id == "a2", second | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 175 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 176 | scheduler.release(first.command_id, first.client_id, token) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 177 | assert clients["chatgpt-work"].inflight == 0 | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 178 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 179 | print(json.dumps({ | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 180 | "ok": True, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 181 | "revision": REVISION, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 182 | "first": first.command_id, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 183 | "second": second.command_id, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 184 | "states": {c.command_id: c.status for c in cmds}, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 185 | "execution_enabled": False, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 186 | }, separators=(",", ":"))) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 187 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 188 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 189 | def main() -> None: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 190 | parser = argparse.ArgumentParser() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 191 | parser.add_argument("--self-test", action="store_true") | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 192 | parser.add_argument("--mode", default="shadow", choices=["shadow"]) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 193 | args = parser.parse_args() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 194 | if args.self_test: | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 195 | self_test() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 196 | return | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 197 | print(json.dumps({ | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 198 | "ok": True, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 199 | "revision": REVISION, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 200 | "mode": args.mode, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 201 | "execution_enabled": False, | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 202 | "note": "Engine only. Live Sheet adapter not enabled yet.", | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 203 | }, separators=(",", ":"))) | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 204 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 205 | | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 206 | if __name__ == "__main__": | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |
| 207 | main() | Use FILE Use as OLD Use as NEW Open Patch Composer +/-3 CONTEXT +/-10 CONTEXT +/-25 CONTEXT Append to Buffer A |