Skip to content

Commit 9fc6c0e

Browse files
committed
Merge branch 'master' of AdRoll/erlmld
2 parents 00f41e8 + 25d28e6 commit 9fc6c0e

File tree

7 files changed

+64
-17
lines changed

7 files changed

+64
-17
lines changed

include/erlmld.hrl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525

2626
-record(stream_record, {
2727
partition_key :: binary(),
28-
timestamp :: non_neg_integer(), % approximate arrival time (ms)
28+
timestamp :: undefined | non_neg_integer(), % approximate arrival time (ms)
2929
delay :: non_neg_integer(), % approximate delay between this record and tip of stream (ms)
3030
sequence_number :: sequence_number(),
31-
data :: binary()
31+
data :: term()
3232
}).
3333

3434
-type worker_state() :: term().

rebar.config

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,18 @@
4242
]}
4343
]}
4444
]}.
45+
46+
{dialyzer, [
47+
{warnings, [unknown, no_return, error_handling]},
48+
{plt_apps, top_level_deps},
49+
{plt_extra_apps, []},
50+
{plt_location, local},
51+
{base_plt_apps, [erts, stdlib, kernel, sasl, runtime_tools, tools]},
52+
{base_plt_location, global}
53+
]}.
54+
55+
{xref_checks,[
56+
undefined_function_calls,
57+
locals_not_used,
58+
deprecated_function_calls
59+
]}.

src/erlmld.app.src

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
{applications,
1818
[kernel,
1919
stdlib,
20+
crypto,
2021
erlexec,
2122
jiffy,
2223
b64fast]},

src/erlmld_batch_processor.erl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
-export([initialize/3,
3434
ready/1,
3535
process_record/2,
36+
checkpointed/3,
3637
shutdown/2]).
3738

3839
-include("erlmld.hrl").
@@ -47,6 +48,10 @@
4748
%% Optional callback to call each time process_record returns a checkpoint.
4849
on_checkpoint :: fun((term(), shard_id()) -> term()),
4950

51+
%% Optional, false by default. Tells whether to log or not every successful
52+
%% checkpoint from the KCL worker.
53+
log_checkpoints :: boolean(),
54+
5055
description :: term(),
5156
shard_id :: shard_id(),
5257
count = 0, % non-ignored records seen
@@ -71,12 +76,14 @@
7176

7277
initialize(Opts, ShardId, ISN) ->
7378
Defaults = #{on_checkpoint => fun(_, _) -> ok end,
79+
log_checkpoints => false,
7480
description => undefined,
7581
enable_subsequence_checkpoints => false},
7682
#{description := Description,
7783
flusher_mod := FlusherMod,
7884
flusher_mod_data := FlusherModData,
7985
on_checkpoint := OnCheckpoint,
86+
log_checkpoints := LogCheckpoints,
8087
flush_interval_ms := FlushIntervalMs,
8188
checkpoint_interval_ms := CheckpointIntervalMs,
8289
watchdog_timeout_ms := WatchdogTimeoutMs,
@@ -85,6 +92,7 @@ initialize(Opts, ShardId, ISN) ->
8592
flusher_mod = FlusherMod,
8693
flusher_state = FlusherMod:init(ShardId, FlusherModData),
8794
on_checkpoint = OnCheckpoint,
95+
log_checkpoints = LogCheckpoints,
8896
description = Description,
8997
shard_id = ShardId,
9098
flush_interval_ms = FlushIntervalMs,
@@ -114,6 +122,14 @@ process_record(#state{last_flush_time = LastFlush,
114122
end,
115123
maybe_checkpoint(update_watchdog(NState)).
116124

125+
checkpointed(#state{log_checkpoints = LogCheckpoints} = State,
126+
SequenceNumber,
127+
Checkpoint) ->
128+
case LogCheckpoints of
129+
true -> error_logger:info_msg("~p checkpointed at ~p (~p)~n", [State, Checkpoint, SequenceNumber]);
130+
false -> ok
131+
end,
132+
{ok, State}.
117133

118134
shutdown(#state{description = Description,
119135
shard_id = ShardId,

src/erlmld_noisy_wrk.erl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
-export([initialize/3,
1515
ready/1,
1616
process_record/2,
17+
checkpointed/3,
1718
shutdown/2]).
1819

1920
-include("erlmld.hrl").
@@ -42,6 +43,12 @@ process_record(#state{shard_id = ShardId, count = Count} = State,
4243
{ok, State#state{count = Count + 1}}
4344
end.
4445

46+
checkpointed(#state{shard_id = ShardId, count = Count} = State,
47+
SequenceNumber,
48+
Checkpoint
49+
) ->
50+
io:format("~p (~p) checkpointed at ~p (~p)~n", [ShardId, Count, Checkpoint, SequenceNumber]),
51+
{ok, State}.
4552

4653
shutdown(#state{shard_id = ShardId, count = Count}, Reason) ->
4754
io:format("~p (~p) shutting down, reason: ~p~n", [ShardId, Count, Reason]),

src/erlmld_worker.erl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
| {ok, worker_state(), checkpoint()}
6464
| {error, term()}.
6565

66+
-callback checkpointed(worker_state(), sequence_number(), checkpoint()) ->
67+
{ok, worker_state()}
68+
| {error, term()}.
69+
6670
-callback shutdown(worker_state(), shutdown_reason()) ->
6771
ok
6872
| {ok, checkpoint()}

src/erlmld_wrk_statem.erl

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,23 @@
119119
handler_data :: term(),
120120

121121
%% connected socket owned by this process:
122-
socket :: gen_tcp:socket(),
122+
socket :: undefined | gen_tcp:socket(),
123123

124124
%% input buffer; responses are small and we need no output buffer:
125-
buf = [] :: list(binary()),
125+
buf = [] :: [binary()],
126126

127127
%% worker state returned from handler module init:
128-
worker_state :: term(),
128+
worker_state :: undefined | term(),
129129

130130
%% if true, the MLD made a processRecords call with the V2 format (supplied
131131
%% millisBehindLatest), so we will checkpoint using the V2 checkpoint format:
132132
is_v2 = false :: boolean(),
133133

134134
%% most recent action name from the peer:
135-
last_request :: binary(),
135+
last_request :: undefined | binary(),
136136

137137
%% last attempted checkpoint:
138-
last_checkpoint :: checkpoint()
138+
last_checkpoint :: undefined | checkpoint()
139139
}).
140140

141141
-define(INTERNAL, internal).
@@ -410,22 +410,26 @@ handle_event(?INTERNAL, #{<<"action">> := <<"checkpoint">>,
410410

411411
handle_event(?INTERNAL, #{<<"action">> := <<"checkpoint">>} = R,
412412
{?DISPATCH, CheckpointState},
413-
#data{worker_state = {ok, WorkerState},
413+
#data{handler_module = Mod,
414+
worker_state = {ok, WorkerState},
414415
last_checkpoint = Checkpoint,
415416
last_request = LastAction} = Data)
416417
when CheckpointState == ?CHECKPOINT;
417418
CheckpointState == ?SHUTDOWN_CHECKPOINT ->
418-
%% successful checkpoint. fixme; provide indication of success to worker?
419419
SN = sequence_number(R),
420-
error_logger:info_msg("~p checkpointed at ~p (~p)~n", [WorkerState, Checkpoint, SN]),
421-
case CheckpointState of
422-
?CHECKPOINT ->
423-
{next_state, ?PROCESS_RECORDS, Data};
424-
?SHUTDOWN_CHECKPOINT ->
425-
success(LastAction, Data, ?SHUTDOWN)
420+
case Mod:checkpointed(WorkerState, SN, Checkpoint) of
421+
{ok, NWorkerState} ->
422+
NData = worker_state(Data, NWorkerState),
423+
case CheckpointState of
424+
?CHECKPOINT ->
425+
{next_state, ?PROCESS_RECORDS, NData};
426+
?SHUTDOWN_CHECKPOINT ->
427+
success(LastAction, NData, ?SHUTDOWN)
428+
end;
429+
{error, _} = Error ->
430+
{stop, Error}
426431
end;
427432

428-
429433
%% we were processing records and we attempted to checkpoint, but failed because another
430434
%% worker stole our lease. abort record processing, return a 'success' response for
431435
%% the current command, and read the next request, which should be a shutdown command.
@@ -586,7 +590,7 @@ next_line(Bin, #data{buf = Buf} = Data) ->
586590
%% and remaining data. an "action" is a line which should have been a json-encoded map
587591
%% containing an "action" key. if decoding fails with a thrown error, that error is
588592
%% returned as the decoded value.
589-
-spec next_action(binary(), #data{}) -> {map() | undefined, #data{}, binary()}.
593+
-spec next_action(binary(), #data{}) -> {map() | undefined | {error, term()}, #data{}, binary()}.
590594
next_action(Bin, Data) ->
591595
case next_line(Bin, Data) of
592596
{undefined, NData, Rest} ->

0 commit comments

Comments
 (0)