Class JournalFileBackend
- Namespace
- OptunaSharp.Storages.Journal
- Assembly
- OptunaSharp.dll
File storage class for Journal log backend.
Port of optuna/storages/journal/_file.py: JournalFileBackend.
The on-disk format is JSON-lines (one compact-separator json.dumps per line,
\n-terminated, UTF-8) — byte-compatible with Python Optuna, so a journal file
written by either side can be continued by the other with no external dependency on
either side (the plan's Tier N cross-language persistence claim).
public class JournalFileBackend : BaseJournalBackend
- Inheritance
-
JournalFileBackend
- Derived
- Inherited Members
Constructors
JournalFileBackend(string, BaseJournalFileLock?)
Opens or creates a UTF-8 JSON-lines journal using the supplied interprocess lock.
public JournalFileBackend(string filePath, BaseJournalFileLock? lockObj = null)
Parameters
filePathstringPath of file to persist the log to.
lockObjBaseJournalFileLockLock object for process exclusivity. An instance of JournalFileSymlinkLock or JournalFileOpenLock can be passed. When
null, the backend uses Optuna's default, the symbolic-link protocol, and switches to the JournalFileOpenLock protocol by itself if this process cannot create symbolic links (see the remarks).
Remarks
Python's backend defaults to JournalFileSymlinkLock, which needs Developer Mode or
the symbolic-link privilege on Windows and a filesystem with symbolic links everywhere. Without
them, Python's first write fails with "A required privilege is not held by the client". The
default lock here keeps the symlink protocol wherever it works and moves to the open-file
protocol instead of failing; both take the same <filePath>.lock path, so this process
still excludes Python workers on the same journal. A lock passed explicitly is used as is: an
explicit JournalFileSymlinkLock still fails where Python's does.
Exceptions
- IOException
The journal file cannot be opened or created.
- UnauthorizedAccessException
The process lacks access to the journal path.
Methods
AppendLogs(IReadOnlyList<OrderedDict<string, object?>>)
Appends compact JSON records while holding the interprocess lock, then flushes data to disk.
public override void AppendLogs(IReadOnlyList<OrderedDict<string, object?>> logs)
Parameters
logsIReadOnlyList<OrderedDict<string, object>>Ordered JSON-serializable records to append as one locked batch.
Exceptions
- IOException
Writing or flushing the journal fails.
- UnauthorizedAccessException
Journal or lock-file access is denied.
- RuntimeError
Releasing the acquired lock fails.
ReadLogs(int)
Reads complete journal records within the file-size snapshot taken when enumeration begins.
public override IEnumerable<OrderedDict<string, object?>> ReadLogs(int logNumberFrom)
Parameters
logNumberFromintZero-based inclusive log number to read.
Returns
- IEnumerable<OrderedDict<string, object>>
Lazy decoded log records; dispose the enumerator to close its file stream.
Remarks
Safe to call from several threads, and from several JournalStorage instances that share this backend: the offset cache is locked per access, and each enumeration tracks its own byte position. Readers never take the journal lock, as in Optuna; a record that a writer is still appending is left for the next read (see the size snapshot below).
Exceptions
- IOException
The journal cannot be read.
- UnauthorizedAccessException
The journal cannot be opened for reading.
- ValueError
A malformed record is followed by another record.
- InvalidCastException
A decoded record is not a JSON object.