336 Commits
Author SHA1 Message Date
Scott Lamb 5944f2bba7 v0.7.31 with retina v0.4.19
Fixes #352
2026-03-13 11:55:44 -07:00
Scott Lamb ffc8bd6b98 v0.7.30: fix severe timestamp drift
* reset local start time at each recording boundary
* include the final frame's time when converting from wall to media time

Together at 30 fps these caused about 15 seconds of drift over 4 hours.
2026-02-19 15:47:00 -08:00
Scott Lamb 10e48265cf v0.7.29: fix garbage collection
As noted in the changelog, this problem caused restarts to take a long
time, and the SQLite database to (slowly) grow without bound.

The problem was simple: the directory worker incorrectly aborted
`collect_garbage` if nothing was watching the result. For some
operations (e.g. reading from sample files) this is the correct
behavior, but in this case it contradicts the `Pool::collect_garbage`
contract.
2026-02-19 10:11:17 -08:00
Scott Lamb b74b643d3e gracefully degrade live stream
See #343
2026-02-19 09:32:24 -08:00
Scott Lamb 7985abfc38 update some Rust deps 2026-02-18 19:24:34 -08:00
Scott Lamb 3b75703652 add SameSite=Lax to logout Set-Cookie header
When clearing the session cookie on logout, the Set-Cookie header had
no SameSite attribute. Older Firefox would warn about automatically
applying SameSite=Lax. Newer Firefox no longer warns, but we might as
well be explicit.

https://bugzilla.mozilla.org/show_bug.cgi?id=1654847
https://bugzilla.mozilla.org/show_bug.cgi?id=1653518

Fixes #292
2026-02-18 13:12:25 -08:00
Scott Lamb 8e2106b042 log full HTTP error chains
For example, this newly logs if a login fails because the user is
disabled.
2026-02-18 12:49:34 -08:00
Scott Lamb dbf4c79644 update retina 2026-02-18 11:49:18 -08:00
Scott Lamb 7fb56fb0b3 fix lock order violations in moonfire-nvr config
These caused debug mode panics. I don't think they lead to any real
deadlocks or problems in release mode.
2026-02-18 11:46:56 -08:00
Scott Lamb a384f2cb2a fix dir pool shutdown with multiple streams
`v0.7.26` introduced a busy loop error when the dir pool was shutting
down with multiple streams. This commit tests and fixes this scenario.

Also fixes a second problem in dropping a writer without an explicit
close would panic in debug mode about using (dropping) the blake3 hasher
while holding a lock. The check is meant to detect slow operations while
holding a lock. The panic wouldn't happen in release mode and probably
isn't a significant source of slowness, but fix it anyway.
2026-02-18 11:19:43 -08:00
Scott Lamb 316d3d8482 allow inserting VSEs without the db lock 2026-02-17 11:55:55 -08:00
Scott Lamb fd7ae68657 overhaul streams!
This puts a lot of state into a new `LockedStream` that was formerly
guarded more coarsely by the recording lock or more granularly by
`RecordingToInsert` locks. And it restructures `LockedDatabase::flush`
to avoid holding this lock while performing SQLite operations.

Streamers write only into a recent frames buffer in RAM, which the
directory pool workers asynchronously write to disk approximately once
per GOP, where formerly there was a write call per frame.

Before, streamers could fall behind due to slow sample file directory
disk I/O calls or if writing got stuck in a retry loop, for example if
out of disk space. If Moonfire falls too far behind in receiving,
cameras tend to disconnect or (sadly) mis-frame messages because they do
not handle this case well. This removes a confusing potential cause of
such errors.

In the new model, streamers never wait for disk I/O. Frames are buffered
up to a limit. Recordings are aborted if the I/O pool falls too far
behind. There's no retry loop.

This roughly halves CPU usage as thread hand-offs and syscalls are less
common. It also enables several desirable future changes:

* audio recording (which radically increases the number of frames and
  thus would otherwise significantly increase CPU usage).
* "monitor mode" (allowing live view without recording to disk),
* further CPU reductions for live view (by skipping all SQLite ops and
  disk I/O).

In the new model, streamers also rarely wait for SQLite database
operations either—now only on video parameter changes. That might go
away in an upcoming change too.

The "syncer" (which synced files/dirs and kept track of what has to be
flushed into the SQLite database when) has mostly gone away too. The
directory pool workers handle the syncing now, and then they notify
a new "flusher" for the latter portion.

I'd like to go further still and have the database as a whole be owned
by a dedicated thread, the only one that uses the SQLite connection.
This prevents the tokio threads from blocking on SQLite operations.
I tried out doing so before making the streamers less dependent on the
db, but the extra thread handoffs were awful for performance.
2026-02-17 11:55:55 -08:00
Scott Lamb 0dc285b159 move all sample file dir I/O to pool
Now, all IO happens on each directory's two-thread pool with threads
named `dir-<PATH>`. Formerly, IO could happen on the per-stream writer
threads, per-directory reader threads, and occasional on even the tokio
worker threads.

The recording path uses more CPU than before due to extra thread
hand-offs. That will change in the next commit, which will radically
change the approach to writing.
2026-02-17 11:17:28 -08:00
Scott Lamb d127b80c87 make even debug builds run decently fast
...by optimizing certain crates that are responsible for most of the CPU
time. Most are self-explanatory.
2026-02-17 11:17:28 -08:00
Scott Lamb ee84b7bdf2 no per-layer filter in test setup
I stopped using it in the production path in 7968700a because per-layer
filters are buggy. Do the same in the test path.
2026-02-16 17:20:35 -08:00
Scott Lamb 4f45a7f34d clarify db ops used by sample file dir code 2026-02-16 17:20:35 -08:00
Scott Lamb f85ce0d66a don't capture backtrace on Unknown
Currently all errors from retina are `Unknown`, and these massive
backtraces are obnoxious when a camera fails on every attempt, with
only a second between.
2026-02-16 17:20:35 -08:00
Scott Lamb c1bf79a01c cloneable Error
This is useful in `mp4::Segment::index`. It will also be useful in
an upcoming change that can fan out errors from directory pool
transitions.
2026-02-16 17:20:35 -08:00
Scott Lamb 424d61f2b5 small tweaks to Docker experience
* add `/var/tmp` to the image so it doesn't have to be mounted
* remove obsolete `version: 3` from compose snippet
* mention `/usr/share/zoneinfo` in error msg and troubleshooting guide
2026-02-16 08:25:19 -08:00
Scott Lamb 20299cab89 update retina 2026-02-14 12:51:48 -08:00
Scott Lamb f1f1a04394 adjust panic handling, debug info in release binaries 2026-02-14 12:48:46 -08:00
Scott Lamb 0cc1aa96d6 quick fix for #346 2026-02-14 12:45:19 -08:00
Scott Lamb 5cc93349fc prep v0.7.22
...with dependency updates, notably including Retina.
2025-10-03 14:48:12 -07:00
Scott Lamb dc1909d073 fix lifetime elision warnings 2025-10-03 14:19:52 -07:00
Jared Wolff bc93712314 Addressing FreeBSD compile issue 2025-06-18 20:46:01 -07:00
Scott Lamb 7968700aae fix missing log lines
...by using a global rather than per-layer filter with `tracing`.
2025-05-08 10:48:53 -07:00
Scott Lamb 1817931c6f update a few Rust deps 2025-04-04 11:48:19 -07:00
Scott Lamb 5147a50771 use mimalloc with musl build fix 2025-04-04 09:23:10 -07:00
Scott Lamb 39b6f6c49c build releases with mimalloc 2025-04-03 10:06:50 -07:00
Scott Lamb 0ccc6d0769 wrap Mutex and Condvar to handle poison
This centralizes a major source of `.unwrap()` throughout the code,
and one that would otherwise grow with upcoming changes. The new
error message should be more clear.
2025-04-03 09:16:44 -07:00
Scott Lamb 2903b680df clippy fixes to tests 2025-04-03 09:16:44 -07:00
Scott Lamb 2985214d87 reduce per-slice allocations
`slices::Slices::get_range` was too closely following the example of
`http_serve::Entity::get_range`:

The latter is once-per-request, so just boxing is low-cost and makes
sense to easily avoid monomorphization bloat when there are potentially
many types of entity streams in one program. In Moonfire, it's used with
different streams defined in the `moonfire_nvr::web::mp4`,
`moonfire_nvr::bundled_ui`, and `http_serve::file` modules. Putting them
all into a single boxless enum would be a pain. In particular, the last
one is not a nameable type today and would need more generic parameters
to implement the caller-demanded `Entity` definition.

The former is once-per-slice, there are tons of slices per request, and
it's easy to define a two-case enum right where it's needed. So the
trade-off is quite different.

Also fix up some out-of-date comments.
2025-03-07 18:54:41 -08:00
Scott Lamb 3cc9603ff3 resurrect benches
Because these require nightly, CI isn't configured to fail if they're
broken. And they have been broken since the conversion to hyper 1.x.
2025-03-07 09:26:35 -08:00
Scott Lamb f894f889be log full error chain in a couple spots 2025-03-06 21:05:43 -08:00
Scott Lamb 0bfa09b1f1 drop ulid dependency
...and use v7 UUIDs exclusively. It's useful to have the timestamp in
request ids in particular, and no reason we _need_ v4 anywhere.
2025-02-07 10:04:29 -08:00
Scott Lamb d780b28cc2 remove unused cstr dep 2025-02-07 09:07:32 -08:00
Scott Lamb d75d8d0b96 prep v0.7.20 2025-01-31 21:32:00 -08:00
Scott Lamb 738ad9a558 get rid of UnsafeCell usage 2025-01-28 21:36:00 -08:00
Scott Lamb 24bbb024ee prep v0.7.19 2025-01-28 09:25:58 -08:00
Scott Lamb b4836f3abb v0.7.18: support H.265
There's no transcoding, so if the browser/player doesn't support these
formats, they don't play. But it will record and allow downloads, and
it seems to be working with Chrome on macOS at least.

Fixes #33
2025-01-28 09:05:10 -08:00
Scott Lamb dd30d5bcf8 update Rust dependencies
This pulls in a duplicate version of `thiserror` for now, but oh well.
2025-01-25 10:40:21 -08:00
Scott Lamb cbb2c30b56 use jiff crate 2025-01-22 14:16:31 -08:00
Scott Lamb c46832369a automated clippy fixes 2025-01-22 09:40:25 -08:00
Scott Lamb 904842cc2d improve error msg on timeout opening stream
Before, it'd look like the following, as mentioned in
https://github.com/scottlamb/moonfire-nvr/issues/331:

```
2024-12-09T20:53:24.853572 WARN s-CP3PRO-main streamer{stream="CP3PRO-main"}: moonfire_nvr::streamer: sleeping for 1 s after error err=UNKNOWN
caused by: deadline has elapsed
```

...which isn't as clear as it could be, particularly if you don't notice
the `caused by` bit. After, it should look more like the following:

```
2024-12-09T20:53:24.853572 WARN s-CP3PRO-main streamer{stream="CP3PRO-main"}: moonfire_nvr::streamer: sleeping for 1 s after error err=DEADLINE_EXCEEDED unable to play stream and get first frame within PT30S
caused by: deadline has elapsed
```
2024-12-11 15:06:28 -08:00
Scott Lamb 9256561362 fix a couple clippy errors
...with Rust 1.82.
2024-12-11 15:03:31 -08:00
Scott Lamb 3efff2cfd6 improve end reason in list ui
* in backend, save the full reason, not just the most direct error,
  which is often the useless `UNKNOWN`

* in UI, instead of wrapping in `<Typography>` which just resorts in
  a weird ransom-note mixed size look, reserve space for or actually
  use an icon.
2024-09-01 22:18:01 -07:00
Scott Lamb 1473e79e96 upgrade to hyper/http 1.0
In the process, no longer wait for pending HTTP requests on shutdown.
This just extended the time Moonfire was running without streaming.
2024-08-31 20:07:33 -07:00
Scott Lamb 8b951200c9 print usage on no args again
This regressed with f9e3fb56b3 due to
<https://github.com/pacak/bpaf/issues/385>.
2024-08-31 07:18:18 -07:00
Scott Lamb 06f942582c update cursive
`cursive` now requires `Send + Sync` bounds, so I had to switch from
`Rc<RefCell<...>>` to `Arc<Mutex<...>>`. I also coalesced some
lock calls together, hopefully without introducing any deadlocks.
I don't see any calls into the UI that would need the model while these
are held, and it seemed fine in a quick test.
2024-08-24 13:13:52 -07:00
Scott Lamb f9e3fb56b3 update some deps 2024-08-23 21:37:21 -07:00