Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ main, develop ]
branches: [ main, devel ]
pull_request:
branches: [ main, develop ]
branches: [ main, devel ]

jobs:
test:
Expand Down Expand Up @@ -62,10 +62,10 @@ jobs:
uv run coverage xml -o coverage.xml
uv run coverage json -o coverage.json
- name: Build PR coverage comment
if: github.event_name == 'pull_request' && (github.base_ref == 'main' || github.base_ref == 'develop')
if: github.event_name == 'pull_request' && (github.base_ref == 'main' || github.base_ref == 'devel')
run: python scripts/build_coverage_comment.py
- name: Post sticky PR coverage comment
if: github.event_name == 'pull_request' && (github.base_ref == 'main' || github.base_ref == 'develop')
if: github.event_name == 'pull_request' && (github.base_ref == 'main' || github.base_ref == 'devel')
uses: marocchino/sticky-pull-request-comment@v2
with:
header: coverage-report
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Compatibility

on:
push:
branches: [ main, develop ]
branches: [ main, devel ]
pull_request:
branches: [ main, develop ]
branches: [ main, devel ]
types: [opened, synchronize, reopened, labeled]
schedule:
- cron: "0 3 * * *"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

On-device ML inference monitoring for Python. Tracks latency, errors, and model metadata without any code modifications.

> **Pre-release:** The API is unstable and may change between versions.
> **Pre-release:** The API is unstable and may change between versions. Semantic versioning will apply from the first stable release.

## Install

Expand Down
2 changes: 0 additions & 2 deletions tests/test_platform_linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ def test_real_cpu_freq():
assert 0 < cur <= 10_000
if max_f is not None:
assert 0 < max_f <= 10_000
if cur is not None and max_f is not None:
assert cur <= max_f


@pytest.mark.requires_linux
Expand Down
24 changes: 24 additions & 0 deletions tests/test_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ def test_persistent_queue_rehydrates_from_disk(self, tmp_path):
assert q2.length() == 2
assert q2.peek() == make_event(1)

def test_persistent_queue_rehydrates_order_when_timestamps_collide(
self, tmp_path, monkeypatch
):
fixed_ns = 1_000_000_000_000_000_000
monkeypatch.setattr("wildedge.queue.time.time_ns", lambda: fixed_ns)

q1 = EventQueue(
max_size=10,
policy=QueuePolicy.OPPORTUNISTIC,
persist_to_disk=True,
disk_dir=str(tmp_path),
)
for i in range(5):
q1.add(make_event(i))

q2 = EventQueue(
max_size=10,
policy=QueuePolicy.OPPORTUNISTIC,
persist_to_disk=True,
disk_dir=str(tmp_path),
)
assert q2.length() == 5
assert [e["event_id"] for e in q2.peek_many(5)] == ["0", "1", "2", "3", "4"]

def test_persistent_queue_remove_deletes_files(self, tmp_path):
q = EventQueue(
max_size=10,
Expand Down
4 changes: 3 additions & 1 deletion wildedge/queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def __init__(
self.disk_dir = Path(disk_dir).expanduser() if disk_dir else None
self._event_paths: deque[Path] = deque()
self.lock = threading.Lock()
self._persist_seq = 0
if self.persist_to_disk:
if self.disk_dir is None:
raise ValueError("disk_dir is required when persist_to_disk=True")
Expand Down Expand Up @@ -63,7 +64,8 @@ def persist_event(self, event: dict) -> None:
if not self.persist_to_disk:
return
assert self.disk_dir is not None
filename = f"{time.time_ns()}-{uuid.uuid4()}.json"
filename = f"{time.time_ns():020d}-{self._persist_seq:010d}-{uuid.uuid4()}.json"
self._persist_seq += 1
path = self.disk_dir / filename
path.write_text(json.dumps(event, separators=(",", ":"), ensure_ascii=True))
self._event_paths.append(path)
Expand Down
Loading