Skip to content

Commit ed36ebd

Browse files
authored
update!: modified run and txn align with Rust implementation (#40)
1 parent 10c26a1 commit ed36ebd

File tree

5 files changed

+139
-174
lines changed

5 files changed

+139
-174
lines changed

src/main/java/com/github/sttk/sabi/DataHub.java

Lines changed: 16 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,6 @@ public record CreatedDataConnIsNull(String name, String dataConnType) {}
8888
*/
8989
public record FailToCastDataConn(String name, String castToType) {}
9090

91-
/**
92-
* Represents an error reason that occurred when failing to cast the {@code DataHub} instance
93-
* itself to the expected data access interface type for a {@link Logic}.
94-
*
95-
* @param castFromType The actual type of the {@code DataHub} instance that failed to cast.
96-
*/
97-
public record FailToCastDataHub(String castFromType) {}
98-
9991
/**
10092
* Represents an unexpected {@link RuntimeException} that occurred during pre-commit or commit
10193
* operations.
@@ -128,71 +120,6 @@ public void disuses(String name) {
128120
inner.disuses(name);
129121
}
130122

131-
/**
132-
* Executes the provided application {@link Logic} without transactional boundaries. The {@code
133-
* DataHub} instance itself is passed as the data access object {@code D} to the {@link Logic}'s
134-
* {@code run} method.
135-
*
136-
* @param <D> The type of the data access object, which typically is {@code DataHub} or an
137-
* interface implemented by {@code DataHub} that {@link Logic} expects.
138-
* @param logic The application logic to execute.
139-
* @throws Exc if an {@link Exc} or {@link RuntimeException} occurs during logic execution or if
140-
* the {@code DataHub} cannot be cast to the expected data access type.
141-
*/
142-
public <D> void run(Logic<D> logic) throws Exc {
143-
D data;
144-
try {
145-
@SuppressWarnings("unchecked")
146-
D d = (D) this;
147-
data = d;
148-
} catch (Exception e) {
149-
throw new Exc(new FailToCastDataHub(this.getClass().getName()));
150-
}
151-
try {
152-
inner.begin();
153-
logic.run(data);
154-
} catch (Exc | RuntimeException e) {
155-
throw e;
156-
} finally {
157-
inner.end();
158-
}
159-
}
160-
161-
/**
162-
* Executes the provided application {@link Logic} within a transactional context. The {@code
163-
* DataHub} instance is passed as the data access object {@code D} to the {@link Logic}'s {@code
164-
* run} method. If the logic completes successfully, a commit operation is attempted. If any
165-
* {@link Exc}, {@link RuntimeException}, or {@link Error} occurs, a rollback operation is
166-
* performed.
167-
*
168-
* @param <D> The type of the data access object, which typically is {@code DataHub} or an
169-
* interface implemented by {@code DataHub} that {@link Logic} expects.
170-
* @param logic The application logic to execute transactionally.
171-
* @throws Exc if an {@link Exc}, {@link RuntimeException}, or {@link Error} occurs during logic
172-
* execution, pre-commit, or commit. The original exception is re-thrown after rollback.
173-
*/
174-
public <D> void txn(Logic<D> logic) throws Exc {
175-
D data;
176-
try {
177-
@SuppressWarnings("unchecked")
178-
D d = (D) this;
179-
data = d;
180-
} catch (Exception e) {
181-
throw new Exc(new FailToCastDataHub(this.getClass().getName()));
182-
}
183-
try {
184-
inner.begin();
185-
logic.run(data);
186-
inner.commit();
187-
inner.postCommit();
188-
} catch (Exc | RuntimeException | Error e) {
189-
inner.rollback();
190-
throw e;
191-
} finally {
192-
inner.end();
193-
}
194-
}
195-
196123
/**
197124
* Retrieves a {@link DataConn} instance from the managed data sources. This method is part of the
198125
* {@link DataAcc} interface implementation.
@@ -218,4 +145,20 @@ public <C extends DataConn> C getDataConn(String name, Class<C> cls) throws Exc
218145
public void close() {
219146
inner.close();
220147
}
148+
149+
void begin() throws Exc {
150+
inner.begin();
151+
}
152+
153+
void commit() throws Exc {
154+
inner.commit();
155+
}
156+
157+
void rollback() {
158+
inner.rollback();
159+
}
160+
161+
void end() {
162+
inner.end();
163+
}
221164
}

src/main/java/com/github/sttk/sabi/Sabi.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434
* }</code></pre>
3535
*/
3636
public final class Sabi {
37+
/**
38+
* Represents an error reason that occurred when failing to cast the {@code DataHub} instance
39+
* itself to the expected data access interface type for a {@link Logic}.
40+
*
41+
* @param castFromType The actual type of the {@code DataHub} instance that failed to cast.
42+
*/
43+
public record FailToCastDataHub(String castFromType) {}
44+
3745
private Sabi() {}
3846

3947
/**
@@ -63,4 +71,72 @@ public static void uses(String name, DataSrc ds) {
6371
public static AutoCloseable setup() throws Exc {
6472
return DataHubInner.setupGlobals();
6573
}
74+
75+
/**
76+
* Executes the provided application {@link Logic} without transactional boundaries. The {@code
77+
* DataHub} instance in the parameters is passed as the data access object {@code D} to the {@link
78+
* Logic}'s {@code run} method.
79+
*
80+
* @param <D> The type of the data access object, which typically is {@code DataHub} or an
81+
* interface implemented by {@code DataHub} that {@link Logic} expects.
82+
* @param logic The application logic to execute.
83+
* @param hub An instance of a DataHub subclass that inherits the data interface for logic
84+
* arguments.
85+
* @throws Exc if an {@link Exc} or {@link RuntimeException} occurs during logic execution or if
86+
* the {@code DataHub} cannot be cast to the expected data access type.
87+
*/
88+
public static <D> void run(Logic<D> logic, DataHub hub) throws Exc {
89+
D data;
90+
try {
91+
@SuppressWarnings("unchecked")
92+
D d = (D) hub;
93+
data = d;
94+
} catch (Exception e) {
95+
throw new Exc(new FailToCastDataHub(hub.getClass().getName()));
96+
}
97+
try {
98+
hub.begin();
99+
logic.run(data);
100+
} catch (Exc | RuntimeException e) {
101+
throw e;
102+
} finally {
103+
hub.end();
104+
}
105+
}
106+
107+
/**
108+
* Executes the provided application {@link Logic} within a transactional context. The {@code
109+
* DataHub} instance in the parameter is passed as the data access object {@code D} to the {@link
110+
* Logic}'s {@code run} method. If the logic completes successfully, a commit operation is
111+
* attempted. If any {@link Exc}, {@link RuntimeException}, or {@link Error} occurs, a rollback
112+
* operation is performed.
113+
*
114+
* @param <D> The type of the data access object, which typically is {@code DataHub} or an
115+
* interface implemented by {@code DataHub} that {@link Logic} expects.
116+
* @param logic The application logic to execute transactionally.
117+
* @param hub An instance of a DataHub subclass that inherits the data interface for logic
118+
* arguments.
119+
* @throws Exc if an {@link Exc}, {@link RuntimeException}, or {@link Error} occurs during logic
120+
* execution, pre-commit, or commit. The original exception is re-thrown after rollback.
121+
*/
122+
public static <D> void txn(Logic<D> logic, DataHub hub) throws Exc {
123+
D data;
124+
try {
125+
@SuppressWarnings("unchecked")
126+
D d = (D) hub;
127+
data = d;
128+
} catch (Exception e) {
129+
throw new Exc(new FailToCastDataHub(hub.getClass().getName()));
130+
}
131+
try {
132+
hub.begin();
133+
logic.run(data);
134+
hub.commit();
135+
} catch (Exc | RuntimeException | Error e) {
136+
hub.rollback();
137+
throw e;
138+
} finally {
139+
hub.end();
140+
}
141+
}
66142
}

src/main/java/com/github/sttk/sabi/internal/DataHubInner.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,30 +138,28 @@ public void commit() throws Exc {
138138
if (!excMap.isEmpty()) {
139139
throw new Exc(new DataHub.FailToCommitDataConn(excMap));
140140
}
141-
}
142141

143-
public void rollback() {
144-
var ag = new AsyncGroupImpl();
145-
var ptr = this.dataConnList.head;
142+
ag = new AsyncGroupImpl();
143+
ptr = this.dataConnList.head;
146144
while (ptr != null) {
147145
ag.name = ptr.name;
148-
if (ptr.conn.shouldForceBack()) {
149-
ptr.conn.forceBack(ag);
150-
} else {
151-
ptr.conn.rollback(ag);
152-
}
146+
ptr.conn.postCommit(ag);
153147
ptr = ptr.next;
154148
}
155149

156150
ag.joinAndIgnoreExcs();
157151
}
158152

159-
public void postCommit() {
153+
public void rollback() {
160154
var ag = new AsyncGroupImpl();
161155
var ptr = this.dataConnList.head;
162156
while (ptr != null) {
163157
ag.name = ptr.name;
164-
ptr.conn.postCommit(ag);
158+
if (ptr.conn.shouldForceBack()) {
159+
ptr.conn.forceBack(ag);
160+
} else {
161+
ptr.conn.rollback(ag);
162+
}
165163
ptr = ptr.next;
166164
}
167165

src/test/java/com/github/sttk/sabi/internal/DataAccTest.java

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ void test() {
316316

317317
try (var ac = Sabi.setup()) {
318318
suppressWarnings_unused(ac);
319-
try (var hub = new SampleDataHub()) {
320-
hub.run(new SampleLogic());
319+
try (var data = new SampleDataHub()) {
320+
Sabi.run(new SampleLogic(), data);
321321
} catch (Exception e) {
322322
fail(e);
323323
}
@@ -358,11 +358,11 @@ void test() {
358358

359359
try (var ac = Sabi.setup()) {
360360
suppressWarnings_unused(ac);
361-
try (var hub = new SampleDataHub()) {
362-
hub.uses("foo", new FooDataSrc(1, "hello", logger, false));
363-
hub.uses("bar", new BarDataSrc(2, logger, false));
361+
try (var data = new SampleDataHub()) {
362+
data.uses("foo", new FooDataSrc(1, "hello", logger, false));
363+
data.uses("bar", new BarDataSrc(2, logger, false));
364364

365-
hub.run(new SampleLogic());
365+
Sabi.run(new SampleLogic(), data);
366366
} catch (Exception e) {
367367
fail(e);
368368
}
@@ -390,11 +390,11 @@ void test_not_run_logic_if_fail_to_setup_local_data_src() {
390390

391391
try (var ac = Sabi.setup()) {
392392
suppressWarnings_unused(ac);
393-
try (var hub = new SampleDataHub()) {
394-
hub.uses("foo", new FooDataSrc(1, "hello", logger, true));
395-
hub.uses("bar", new BarDataSrc(2, logger, false));
393+
try (var data = new SampleDataHub()) {
394+
data.uses("foo", new FooDataSrc(1, "hello", logger, true));
395+
data.uses("bar", new BarDataSrc(2, logger, false));
396396

397-
hub.run(new SampleLogic());
397+
Sabi.run(new SampleLogic(), data);
398398
} catch (Exc e) {
399399
switch (e.getReason()) {
400400
case DataHub.FailToSetupLocalDataSrcs r -> {
@@ -434,10 +434,10 @@ void test() {
434434

435435
try (var ac = Sabi.setup()) {
436436
suppressWarnings_unused(ac);
437-
try (var hub = new SampleDataHub()) {
438-
hub.uses("foo", new FooDataSrc(2, "Hello", logger, false));
437+
try (var data = new SampleDataHub()) {
438+
data.uses("foo", new FooDataSrc(2, "Hello", logger, false));
439439

440-
hub.run(new SampleLogic());
440+
Sabi.run(new SampleLogic(), data);
441441
} catch (Exception e) {
442442
fail(e);
443443
}
@@ -481,8 +481,8 @@ void test() {
481481

482482
try (var ac = Sabi.setup()) {
483483
suppressWarnings_unused(ac);
484-
try (var hub = new SampleDataHub()) {
485-
hub.txn(new SampleLogic());
484+
try (var data = new SampleDataHub()) {
485+
Sabi.txn(new SampleLogic(), data);
486486
} catch (Exception e) {
487487
fail(e);
488488
}
@@ -529,11 +529,11 @@ void test() {
529529

530530
try (var ac = Sabi.setup()) {
531531
suppressWarnings_unused(ac);
532-
try (var hub = new SampleDataHub()) {
533-
hub.uses("foo", new FooDataSrc(1, "Hello", logger, false));
534-
hub.uses("bar", new BarDataSrc(2, logger, false));
532+
try (var data = new SampleDataHub()) {
533+
data.uses("foo", new FooDataSrc(1, "Hello", logger, false));
534+
data.uses("bar", new BarDataSrc(2, logger, false));
535535

536-
hub.txn(new SampleLogic());
536+
Sabi.txn(new SampleLogic(), data);
537537
} catch (Exception e) {
538538
fail(e);
539539
}
@@ -567,11 +567,11 @@ void test_not_run_logic_if_fail_to_setup_local_data_src() {
567567

568568
try (var ac = Sabi.setup()) {
569569
suppressWarnings_unused(ac);
570-
try (var hub = new SampleDataHub()) {
571-
hub.uses("foo", new FooDataSrc(1, "Hello", logger, true));
572-
hub.uses("bar", new BarDataSrc(2, logger, false));
570+
try (var data = new SampleDataHub()) {
571+
data.uses("foo", new FooDataSrc(1, "Hello", logger, true));
572+
data.uses("bar", new BarDataSrc(2, logger, false));
573573

574-
hub.txn(new SampleLogic());
574+
Sabi.txn(new SampleLogic(), data);
575575
} catch (Exc e) {
576576
switch (e.getReason()) {
577577
case DataHub.FailToSetupLocalDataSrcs r -> {
@@ -596,11 +596,11 @@ void test_not_run_logic_in_txn_and_rollback() {
596596

597597
try (var ac = Sabi.setup()) {
598598
suppressWarnings_unused(ac);
599-
try (var hub = new SampleDataHub()) {
600-
hub.uses("foo", new FooDataSrc(1, "Hello", logger, false));
601-
hub.uses("bar", new BarDataSrc(2, logger, false));
599+
try (var data = new SampleDataHub()) {
600+
data.uses("foo", new FooDataSrc(1, "Hello", logger, false));
601+
data.uses("bar", new BarDataSrc(2, logger, false));
602602

603-
hub.txn(new FailingLogic());
603+
Sabi.txn(new FailingLogic(), data);
604604
} catch (Exc e) {
605605
assertThat(e.getReason()).isEqualTo("ZZZ");
606606
} catch (Exception e) {
@@ -640,10 +640,10 @@ void test() {
640640

641641
try (var ac = Sabi.setup()) {
642642
suppressWarnings_unused(ac);
643-
try (var hub = new SampleDataHub()) {
644-
hub.uses("foo", new FooDataSrc(2, "Hello", logger, false));
643+
try (var data = new SampleDataHub()) {
644+
data.uses("foo", new FooDataSrc(2, "Hello", logger, false));
645645

646-
hub.txn(new SampleLogic());
646+
Sabi.txn(new SampleLogic(), data);
647647
} catch (Exception e) {
648648
fail(e);
649649
}

0 commit comments

Comments
 (0)