fix outbox metadata

This commit is contained in:
anlicheng 2026-05-12 16:53:41 +08:00
parent 50864cf7bd
commit 23796c9013

View File

@ -8,10 +8,10 @@
%%%
%%%
%%% - `segment-N.log' segment record
%%% - `metadata.term' #{write_seq => N, acked_seq => N,
%%% writer_segment => N} segment segment
%%% 使 metadata
%%%
%%% - `metadata.json'使 JSON write_seqacked_seq
%%% writer_segment segment segment
%%% 使 metadata
%%%
%%% - outbox open/1 dir
%%%
%%% open/1
@ -89,7 +89,7 @@
-type outbox() :: #outbox{}.
-define(METADATA_FILE, "metadata.term").
-define(METADATA_FILE, "metadata.json").
-define(SEGMENT_PREFIX, "segment-").
-define(SEGMENT_EXT, ".log").
-define(RECORD_MAGIC, <<"EFKAOBX1">>).
@ -222,18 +222,32 @@ positive_option(Key, Options) ->
read_metadata(MetadataPath) ->
case file:read_file(MetadataPath) of
{ok, Bin} ->
safe_metadata(binary_to_term(Bin, [safe]));
decode_metadata(Bin);
{error, _} ->
{0, 0, 1}
end.
-spec decode_metadata(binary()) -> {non_neg_integer(), non_neg_integer(), pos_integer()}.
decode_metadata(Bin) ->
try json:decode(Bin) of
Metadata ->
safe_metadata(Metadata)
catch
_:_Reason ->
{0, 0, 1}
end.
-spec safe_metadata(term()) -> {non_neg_integer(), non_neg_integer(), pos_integer()}.
safe_metadata(#{write_seq := WriteSeq, acked_seq := AckedSeq, writer_segment := WriterSegment})
safe_metadata(#{
<<"write_seq">> := WriteSeq,
<<"acked_seq">> := AckedSeq,
<<"writer_segment">> := WriterSegment
})
when is_integer(WriteSeq), WriteSeq >= 0,
is_integer(AckedSeq), AckedSeq >= 0,
is_integer(WriterSegment), WriterSegment > 0 ->
{WriteSeq, AckedSeq, WriterSegment};
safe_metadata(#{write_seq := WriteSeq, acked_seq := AckedSeq})
safe_metadata(#{<<"write_seq">> := WriteSeq, <<"acked_seq">> := AckedSeq})
when is_integer(WriteSeq), WriteSeq >= 0, is_integer(AckedSeq), AckedSeq >= 0 ->
{WriteSeq, AckedSeq, 1};
safe_metadata(_) ->
@ -246,11 +260,11 @@ persist_metadata(#outbox{
write_seq = WriteSeq,
acked_seq = AckedSeq
}) ->
Metadata = term_to_binary(#{
write_seq => WriteSeq,
acked_seq => AckedSeq,
writer_segment => WriterSegment
}),
Metadata = iolist_to_binary(json:encode(#{
<<"write_seq">> => WriteSeq,
<<"acked_seq">> => AckedSeq,
<<"writer_segment">> => WriterSegment
})),
TmpPath = MetadataPath ++ ".tmp",
case file:write_file(TmpPath, Metadata, [write, binary]) of
ok ->