Skip to content

Commit bb87d4f

Browse files
committed
Making the 2pc example more interesting
During the 2pc process, the process will be retried up to 4 times. If all attempts fail, the process will end immediately.
1 parent 2632163 commit bb87d4f

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

examples/two_phase_commit_generic.zig

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,23 @@ const AllRole = enum { selector, alice, bob, charlie };
8585

8686
const AliceContext = struct {
8787
counter: u32 = 0,
88+
retry_times: u32 = 0,
8889
xoshiro256: std.Random.Xoshiro256 = undefined,
8990
pingpong_client: pingpong.ClientContext = .{ .client_counter = 0 },
9091
pingpong_server: pingpong.ServerContext = .{ .server_counter = 0 },
9192
};
9293

9394
const BobContext = struct {
9495
counter: u32 = 0,
96+
retry_times: u32 = 0,
9597
xoshiro256: std.Random.Xoshiro256 = undefined,
9698
pingpong_client: pingpong.ClientContext = .{ .client_counter = 0 },
9799
pingpong_server: pingpong.ServerContext = .{ .server_counter = 0 },
98100
};
99101

100102
const CharlieContext = struct {
101103
counter: u32 = 0,
104+
retry_times: u32 = 0,
102105
xoshiro256: std.Random.Xoshiro256 = undefined,
103106
pingpong_client: pingpong.ClientContext = .{ .client_counter = 0 },
104107
pingpong_server: pingpong.ServerContext = .{ .server_counter = 0 },
@@ -134,33 +137,22 @@ fn PingPong(client: AllRole, server: AllRole, Next: type) type {
134137
}
135138

136139
fn CAB(Next: type) type {
137-
return mk2pc(AllRole, .charlie, .alice, .bob, Context{}, Next);
140+
return mk2pc(AllRole, .charlie, .alice, .bob, Context{}, Next, ps.Exit);
138141
}
139142
fn ABC(Next: type) type {
140-
return mk2pc(AllRole, .alice, .bob, .charlie, Context{}, Next);
143+
return mk2pc(AllRole, .alice, .bob, .charlie, Context{}, Next, ps.Exit);
141144
}
142145
fn BAC(Next: type) type {
143-
return mk2pc(AllRole, .bob, .alice, .charlie, Context{}, Next);
146+
return mk2pc(AllRole, .bob, .alice, .charlie, Context{}, Next, ps.Exit);
144147
}
145148

146149
//Randomly select a 2pc protocol
147150
pub const Random2pc = union(enum) {
148-
charlie_as_coordinator: Data(
149-
void,
150-
PingPong(
151-
.alice,
152-
.bob,
153-
PingPong(
154-
.bob,
155-
.charlie,
156-
PingPong(
157-
.charlie,
158-
.alice,
159-
CAB(@This()).Start,
160-
).Start,
161-
).Start,
162-
).Start,
163-
),
151+
charlie_as_coordinator: Data(void, PingPong(.alice, .bob, PingPong(.bob, .charlie, PingPong(
152+
.charlie,
153+
.alice,
154+
CAB(@This()).Start,
155+
).Start).Start).Start),
164156
alice_as_coordinator: Data(void, PingPong(.charlie, .bob, ABC(@This()).Start).Start),
165157
bob_as_coordinator: Data(void, PingPong(.alice, .charlie, BAC(@This()).Start).Start),
166158
exit: Data(void, ps.Exit),
@@ -200,15 +192,16 @@ pub fn mk2pc(
200192
alice: Role,
201193
bob: Role,
202194
context: anytype,
203-
NextFsmState: type,
195+
Successed: type,
196+
Failed: type,
204197
) type {
205198
return struct {
206199
fn two_pc(sender: Role, receiver: []const Role) ps.ProtocolInfo(
207200
"2pc_generic",
208201
Role,
209202
context,
210203
&.{ coordinator, alice, bob },
211-
&.{NextFsmState},
204+
&.{ Successed, Failed },
212205
) {
213206
return .{ .sender = sender, .receiver = receiver };
214207
}
@@ -219,7 +212,7 @@ pub fn mk2pc(
219212
pub const info = two_pc(coordinator, &.{ alice, bob });
220213

221214
pub fn process(ctx: *info.RoleCtx(coordinator)) !@This() {
222-
_ = ctx;
215+
ctx.counter = 0;
223216
return .{ .begin = .{ .data = {} } };
224217
}
225218
};
@@ -266,18 +259,24 @@ pub fn mk2pc(
266259
};
267260

268261
pub const Check = union(enum) {
269-
succcessed: Data(void, NextFsmState),
262+
succcessed: Data(void, Successed),
263+
failed: Data(void, Failed),
270264
failed_retry: Data(void, Start),
271265

272266
pub const info = two_pc(coordinator, &.{ alice, bob });
273267

274268
pub fn process(ctx: *info.RoleCtx(coordinator)) !@This() {
275269
if (ctx.counter == 2) {
276-
ctx.counter = 0;
270+
ctx.retry_times = 0;
277271
return .{ .succcessed = .{ .data = {} } };
272+
} else if (ctx.retry_times < 4) {
273+
ctx.retry_times += 1;
274+
std.debug.print("2pc failed retry: {d}\n", .{ctx.retry_times});
275+
return .{ .failed_retry = .{ .data = {} } };
276+
} else {
277+
ctx.retry_times = 0;
278+
return .{ .failed = .{ .data = {} } };
278279
}
279-
ctx.counter = 0;
280-
return .{ .failed_retry = .{ .data = {} } };
281280
}
282281
};
283282
};

0 commit comments

Comments
 (0)