Table of Contents

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

filePath string

Path of file to persist the log to.

lockObj BaseJournalFileLock

Lock 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

logs IReadOnlyList<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

logNumberFrom int

Zero-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.