Skip to content

Commit baea305

Browse files
committed
Merge branch 'feature/aramallo.v6' into develop
2 parents aa51496 + 36d6d56 commit baea305

8 files changed

Lines changed: 303 additions & 171 deletions

.gitignore

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ results.csv
4040
riak_test/ebin/*.beam
4141
rt/
4242
src/*.swp
43-
# Generated by priv/generate_otp_sources.escript on every compile
44-
src/partisan_gen.erl
45-
src/partisan_gen_event.erl
46-
src/partisan_gen_server.erl
47-
src/partisan_gen_statem.erl
48-
src/partisan_gen_supervisor.erl
49-
src/partisan_proc_lib.erl
50-
src/partisan_sys.erl
5143
tags
5244
TEST-*
5345
test/*/RAND

priv/generate_otp_sources.escript

Lines changed: 90 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
%% -*- erlang -*-
33

44
%% -----------------------------------------------------------------------------
5-
%% Pre-compile generation of partisan OTP module SOURCES.
5+
%% Pre-compile generation of partisan OTP module BEAM files.
66
%%
77
%% Why a pre-compile (and not a post-compile) hook?
88
%% ------------------------------------------------
@@ -12,23 +12,25 @@
1212
%% had a chance to fire. plum_db then fails because
1313
%% `partisan_gen_supervisor' does not yet exist.
1414
%%
15-
%% This pre-compile script writes `partisan_gen_server.erl',
16-
%% `partisan_gen_supervisor.erl', etc. as real source files into
17-
%% `src/'. They are then compiled by rebar3 as part of partisan's normal
18-
%% compile phase — so by the time downstream deps start compiling,
19-
%% the `partisan_gen_*' beams already exist.
15+
%% Why .beam (and not .erl source)?
16+
%% --------------------------------
17+
%% `erl_pp:form/1' silently strips the `erlang:' prefix from auto-
18+
%% imported BIF calls (e.g. `erlang:spawn_opt' becomes `spawn_opt'). In
19+
%% the rewritten `partisan_proc_lib' there are LOCAL functions named
20+
%% `spawn_opt/2,3,4,5', so a bare `spawn_opt(...)' call resolves to the
21+
%% local function — causing infinite recursion. Compiling forms
22+
%% directly to .beam preserves the AST exactly and avoids the issue.
2023
%%
2124
%% The three support modules (`partisan_otp_rewrite',
2225
%% `partisan_otp_patches', `partisan_gen_transform') have no inter-
23-
%% include dependencies, so we compile them in-memory here and load them
24-
%% before invoking the generator.
26+
%% include dependencies, so we compile them in-memory here and load
27+
%% them before invoking the generator.
2528
%% -----------------------------------------------------------------------------
2629

2730
main(_Args) ->
2831
SrcDir = "src",
32+
EbinDir = ebin_dir(),
2933

30-
%% Sanity check: this script is meant to run from the partisan dep's
31-
%% root directory, where `src/' exists.
3234
case filelib:is_dir(SrcDir) of
3335
true -> ok;
3436
false ->
@@ -39,10 +41,6 @@ main(_Args) ->
3941
halt(1)
4042
end,
4143

42-
%% Compile the three support modules in dependency-call order.
43-
%% Erlang modules can be compiled independently (calls are dynamic),
44-
%% so the only constraint is that each is loaded into the BEAM
45-
%% before `generate_sources/1' invokes it.
4644
SupportModules = [
4745
"partisan_otp_rewrite.erl",
4846
"partisan_otp_patches.erl",
@@ -52,42 +50,105 @@ main(_Args) ->
5250
lists:foreach(fun(File) -> compile_and_load(File, SrcDir) end,
5351
SupportModules),
5452

55-
case partisan_gen_transform:generate_sources(SrcDir) of
53+
ok = filelib:ensure_dir(filename:join(EbinDir, "dummy")),
54+
55+
case partisan_gen_transform:generate_all(EbinDir) of
5656
ok ->
5757
Modules = partisan_gen_transform:modules(),
5858
io:format(
59-
"Generated ~p partisan OTP module sources into ~s/~n",
60-
[length(Modules), SrcDir]
59+
"Generated ~p partisan OTP module beams into ~s/~n",
60+
[length(Modules), EbinDir]
6161
),
62+
update_app_src(SrcDir, Modules),
6263
ok;
6364
{error, Errors} ->
6465
io:format(standard_error,
65-
"Failed to generate partisan OTP module sources:~n~p~n",
66+
"Failed to generate partisan OTP module beams:~n~p~n",
6667
[Errors]),
6768
halt(1)
6869
end.
6970

7071

72+
%% Locate the ebin directory for partisan. Honours rebar3's
73+
%% `REBAR_BUILD_DIR' env var when running as a dep, falling back to a
74+
%% sensible local path when running from partisan's own repo.
75+
ebin_dir() ->
76+
case os:getenv("REBAR_BUILD_DIR") of
77+
false ->
78+
filename:absname("ebin");
79+
BuildDir ->
80+
CheckoutsDir = filename:join(
81+
[BuildDir, "checkouts", "partisan", "ebin"]
82+
),
83+
LibDir = filename:join(
84+
[BuildDir, "lib", "partisan", "ebin"]
85+
),
86+
case filelib:is_dir(CheckoutsDir) of
87+
true -> CheckoutsDir;
88+
false -> LibDir
89+
end
90+
end.
91+
92+
93+
%% Update partisan.app.src so the generated module names appear in the
94+
%% modules list. rebar3 reads .app.src to produce the .app file in
95+
%% ebin. Without this step, releases assembled in embedded mode cannot
96+
%% load the generated modules.
97+
update_app_src(SrcDir, OtpModules) ->
98+
AppSrcFile = filename:join(SrcDir, "partisan.app.src"),
99+
case file:consult(AppSrcFile) of
100+
{ok, [{application, partisan, Props}]} ->
101+
ExistingModules = proplists:get_value(modules, Props, []),
102+
RenameMap = #{
103+
gen => partisan_gen,
104+
proc_lib => partisan_proc_lib,
105+
sys => partisan_sys,
106+
gen_server => partisan_gen_server,
107+
gen_event => partisan_gen_event,
108+
gen_statem => partisan_gen_statem,
109+
gen_fsm => partisan_gen_fsm,
110+
supervisor => partisan_gen_supervisor
111+
},
112+
GenModules = [maps:get(M, RenameMap) || M <- OtpModules],
113+
AllModules = lists:usort(ExistingModules ++ GenModules),
114+
case AllModules of
115+
ExistingModules ->
116+
%% No change — leave the file's mtime alone so
117+
%% rebar3's incremental build is happy.
118+
ok;
119+
_ ->
120+
NewProps = lists:keystore(
121+
modules, 1, Props, {modules, AllModules}
122+
),
123+
Content = io_lib:format(
124+
"~p.~n", [{application, partisan, NewProps}]
125+
),
126+
ok = file:write_file(AppSrcFile, Content)
127+
end;
128+
_ ->
129+
ok
130+
end.
131+
132+
71133
compile_and_load(File, SrcDir) ->
72134
Path = filename:join(SrcDir, File),
73-
case compile:file(Path, [binary, return_errors]) of
135+
case compile:file(Path, [binary, return_errors, debug_info]) of
74136
{ok, Mod, Bin} ->
75-
case code:load_binary(Mod, Path, Bin) of
76-
{module, Mod} ->
77-
ok;
78-
{error, Reason} ->
79-
fail("loading", File, Reason)
80-
end;
137+
load_or_fail(Mod, Path, Bin, File);
81138
{ok, Mod, Bin, _Warnings} ->
82-
case code:load_binary(Mod, Path, Bin) of
83-
{module, Mod} -> ok;
84-
{error, Reason} -> fail("loading", File, Reason)
85-
end;
139+
load_or_fail(Mod, Path, Bin, File);
86140
{error, Errors, Warnings} ->
87141
fail("compiling", File, {Errors, Warnings})
88142
end.
89143

90144

145+
load_or_fail(Mod, Path, Bin, File) ->
146+
case code:load_binary(Mod, Path, Bin) of
147+
{module, Mod} -> ok;
148+
{error, Reason} -> fail("loading", File, Reason)
149+
end.
150+
151+
91152
fail(Action, File, Reason) ->
92153
io:format(standard_error,
93154
"generate_otp_sources.escript: error ~s ~s: ~p~n",

src/partisan.app.src

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
1-
{application, partisan, [
2-
{description,
3-
"Partisan is a scalable and flexible, TCP-based membership system and distribution layer for the BEAM."
4-
},
5-
{vsn, "5.0.3"},
6-
{registered, []},
7-
{applications, [
8-
kernel,
9-
stdlib,
10-
crypto,
11-
ssl,
12-
types,
13-
uuid,
14-
telemetry
15-
]},
16-
{mod, {partisan_app,[]}},
17-
{modules, []},
18-
{included_applications, []},
19-
{env, [
20-
]},
21-
{licenses, ["Apache-2.0"]},
22-
{links, [
23-
{"Github", "https://github.com/lasp-lang/partisan"},
24-
{"Docs", "https://hex.pm/packages/partisan"}
25-
]}
26-
]}.
1+
{application,partisan,
2+
[{description,"Partisan is a scalable and flexible, TCP-based membership system and distribution layer for the BEAM."},
3+
{vsn,"5.0.3"},
4+
{registered,[]},
5+
{applications,[kernel,stdlib,crypto,ssl,types,uuid,telemetry]},
6+
{mod,{partisan_app,[]}},
7+
{modules,[partisan_gen,partisan_gen_event,partisan_gen_server,
8+
partisan_gen_statem,partisan_gen_supervisor,
9+
partisan_proc_lib,partisan_sys]},
10+
{included_applications,[]},
11+
{env,[]},
12+
{licenses,["Apache-2.0"]},
13+
{links,[{"Github","https://github.com/lasp-lang/partisan"},
14+
{"Docs","https://hex.pm/packages/partisan"}]}]}.

src/partisan_gen_transform.erl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,10 @@ write_beam(Dir, Module, Binary) ->
274274

275275

276276
%% Locate the ebin directory for partisan.
277+
%% `code:lib_dir/2' is deprecated since OTP 28; use `code:lib_dir/1' and
278+
%% join the subdirectory ourselves.
277279
ebin_dir() ->
278-
case code:lib_dir(partisan, ebin) of
280+
case code:lib_dir(partisan) of
279281
{error, _} ->
280282
%% During development/test, search rebar3 output dirs.
281283
Candidates = [
@@ -286,6 +288,6 @@ ebin_dir() ->
286288
[Dir | _] -> filename:absname(Dir);
287289
[] -> filename:absname("_build/default/lib/partisan/ebin")
288290
end;
289-
Dir ->
290-
Dir
291+
LibDir ->
292+
filename:join(LibDir, "ebin")
291293
end.

src/partisan_monitor.erl

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -551,23 +551,24 @@ monitor_nodes(Flag, Opts0) when is_boolean(Flag), is_list(Opts0) ->
551551

552552

553553
init([]) ->
554-
?LOG_WARNING(">>>>> partisan_monitor:init/1 enter"),
554+
%% We trap exits so we get a `terminate/2' callback with reason
555+
%% `shutdown' when the supervisor terminates us. This happens when
556+
%% `partisan_peer_service:manager()' is terminated.
555557
erlang:process_flag(trap_exit, true),
556-
?LOG_WARNING(">>>>> partisan_monitor:init/1 trap_exit set"),
557558

558559
%% We subscribe to node status to implement node monitoring.
560+
%% Certain `partisan_peer_service_manager' implementations might not
561+
%% support the `on_up'/`on_down' events; in those cases this module
562+
%% will not work.
559563
Enabled = subscribe_to_node_status(),
560-
?LOG_WARNING(">>>>> partisan_monitor:init/1 subscribed to node status, enabled=~p", [Enabled]),
561564
_ = persistent_term:put({?MODULE, enabled}, Enabled),
562565

563566
_ = subscribe_to_channel_status(),
564-
?LOG_WARNING(">>>>> partisan_monitor:init/1 subscribed to channel status"),
565567

566-
%% partisan_gen behaviours call monitor/2 and demonitor/1 so being
567-
%% this server one, that would create a deadlock due to a circular call.
568-
%% We use a static dummy ref for those calls to avoid calling ourselves.
568+
%% `partisan_gen' behaviours call `monitor/2' and `demonitor/1'.
569+
%% Since this server is one, calling itself would deadlock — we use
570+
%% a static dummy ref for that case to avoid the round trip.
569571
_ = persistent_term:put(?DUMMY_MREF_KEY, partisan:make_ref()),
570-
?LOG_WARNING(">>>>> partisan_monitor:init/1 dummy ref set"),
571572

572573
TabOpts = [
573574
named_table,
@@ -586,15 +587,13 @@ init([]) ->
586587
%% Tables for node status monitoring
587588
_ = ets:new(?NODE_MON, [duplicate_bag, {keypos, 1} | TabOpts]),
588589
_ = ets:new(?NODE_TYPE_MON, [set, {keypos, 2} | TabOpts]),
589-
?LOG_WARNING(">>>>> partisan_monitor:init/1 ets tables created"),
590590

591591
State = #state{
592592
enabled = Enabled,
593593
requests = #{},
594594
nodes = sets:new([{version, 2}])
595595
},
596596

597-
?LOG_WARNING(">>>>> partisan_monitor:init/1 returning ok"),
598597
{ok, State}.
599598

600599

src/partisan_otp_patches.erl

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,73 +1122,6 @@ sup_do_check_childspec_source() ->
11221122
" child_type = ChildType, modules = Mods}}.\n".
11231123

11241124

1125-
%% format_log_multi/2: The format strings contain literal `supervisor:` which
1126-
%% should be `partisan_gen_supervisor:` in log output.
1127-
sup_format_log_multi_source() ->
1128-
"format_log_multi(#{label := {partisan_gen_supervisor, progress},\n"
1129-
" report := [{partisan_gen_supervisor, SupName},\n"
1130-
" {started, Child}]},\n"
1131-
" #{depth := Depth} = FormatOpts) ->\n"
1132-
" P = p(FormatOpts),\n"
1133-
" Format = lists:append([\" partisan_gen_supervisor: \", P, \"~n\",\n"
1134-
" \" started: \", P, \"~n\"]),\n"
1135-
" Args = case Depth of\n"
1136-
" unlimited -> [SupName, Child];\n"
1137-
" _ -> [SupName, Depth, Child, Depth]\n"
1138-
" end,\n"
1139-
" {Format, Args};\n"
1140-
"format_log_multi(#{label := {partisan_gen_supervisor, _Error},\n"
1141-
" report := [{partisan_gen_supervisor, SupName},\n"
1142-
" {errorContext, Ctxt},\n"
1143-
" {reason, Reason},\n"
1144-
" {offender, Child}]},\n"
1145-
" #{depth := Depth} = FormatOpts) ->\n"
1146-
" P = p(FormatOpts),\n"
1147-
" Format = lists:append([\" partisan_gen_supervisor: \", P, \"~n\",\n"
1148-
" \" errorContext: \", P, \"~n\",\n"
1149-
" \" reason: \", P, \"~n\",\n"
1150-
" \" offender: \", P, \"~n\"]),\n"
1151-
" Args = case Depth of\n"
1152-
" unlimited -> [SupName, Ctxt, Reason, Child];\n"
1153-
" _ -> [SupName, Depth, Ctxt, Depth, Reason, Depth, Child, Depth]\n"
1154-
" end,\n"
1155-
" {Format, Args}.\n".
1156-
1157-
1158-
%% format_log_single/2: Fix single-line format strings to use `partisan_gen_Supervisor`.
1159-
sup_format_log_single_source() ->
1160-
"format_log_single(#{label := {partisan_gen_supervisor, progress},\n"
1161-
" report := [{partisan_gen_supervisor, SupName},\n"
1162-
" {started, Child}]},\n"
1163-
" #{single_line := true, depth := Depth} = FormatOpts) ->\n"
1164-
" P = p(FormatOpts),\n"
1165-
" {ChildFormat, ChildArgs} = format_child_log_single(Child, \"Started:\"),\n"
1166-
" Format = \"partisan_gen_Supervisor: \" ++ P ++ \".\",\n"
1167-
" Args = case Depth of\n"
1168-
" unlimited -> [SupName];\n"
1169-
" _ -> [SupName, Depth]\n"
1170-
" end,\n"
1171-
" {Format ++ ChildFormat, Args ++ ChildArgs};\n"
1172-
"format_log_single(#{label := {partisan_gen_supervisor, _Error},\n"
1173-
" report := [{partisan_gen_supervisor, SupName},\n"
1174-
" {errorContext, Ctxt},\n"
1175-
" {reason, Reason},\n"
1176-
" {offender, Child}]},\n"
1177-
" #{single_line := true, depth := Depth} = FormatOpts) ->\n"
1178-
" P = p(FormatOpts),\n"
1179-
" Format = lists:append([\"partisan_gen_Supervisor: \", P,\n"
1180-
" \". Context: \", P,\n"
1181-
" \". Reason: \", P, \".\"]),\n"
1182-
" {ChildFormat, ChildArgs} = format_child_log_single(Child, \"Offender:\"),\n"
1183-
" Args = case Depth of\n"
1184-
" unlimited -> [SupName, Ctxt, Reason];\n"
1185-
" _ -> [SupName, Depth, Ctxt, Depth, Reason, Depth]\n"
1186-
" end,\n"
1187-
" {Format ++ ChildFormat, Args ++ ChildArgs};\n"
1188-
"format_log_single(Report, FormatOpts) ->\n"
1189-
" format_log_multi(Report, FormatOpts).\n".
1190-
1191-
11921125
%% =============================================================================
11931126
%% INTERNAL: Patch application
11941127
%% =============================================================================

0 commit comments

Comments
 (0)