-
Notifications
You must be signed in to change notification settings - Fork 0
/
disconnect_transaction.dart
120 lines (100 loc) · 3.47 KB
/
disconnect_transaction.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Usage: disconnect_transaction.dart [--continue] [seconds]
//
// Opens a connection, starts a transaction, and runs a query. Between obtaining
// the transaction and running the query, an opportunity is provided for the
// database (or network connection to it) to be stopped, to simulate a fault
// that programs should be able to recover from.
//
// If seconds is provided, the program will wait for that amount of time before
// automatically continuing. Otherwise, it will prompt the user for input before
// continuing.
//
// If the "-c" or "--continue" option is specified, the program will run in
// a continuous loop. Otherwise, it will run once and exit.
import 'dart:async';
import 'dart:io';
import 'package:sqljocky5/sqljocky.dart';
Future main(List<String> arguments) async {
var s = ConnectionSettings(
host: "test.example.com",
port: 3306,
user: "test",
password: "p@ssw0rd",
db: "testdb",
);
// Parse command line arguments
final args = new List<String>.from(arguments);
if (args.remove('-h') || args.remove('--help')) {
print('Usage: disconnect_transaction [--continue|-c] [numSeconds]');
exit(0);
}
final continueMode = (args.remove('-c') || args.remove('--continue'));
int delay; // null means interactive mode
if (1 < args.length) {
stderr.write('Usage error: too many arguments\n');
exit(2);
} else if (args.length == 1) {
try {
delay = int.parse(args[0]); // automatic mode
if (delay < 1) {
stderr.write('Error: number of seconds must be greater than zero\n');
exit(2);
}
} on FormatException {
stderr.write('Error: number of seconds is not an integer: ${args[0]}\n');
exit(2);
}
} else {
delay = null; // interactive mode
}
print('Database: ${s.host}:${s.port}: ${s.db}');
do {
final runTime = new DateTime.now();
try {
// Open a connection and get a transaction
final conn = await MySqlConnection.connect(s);
final tx = await conn.begin();
// Provide an opportunity for a network fault or database outage
if (delay == null) {
// Interactive mode
stdout.write("Stop the database and press enter to continue... ");
var line = stdin.readLineSync().trim().toLowerCase();
if (line == 'q') {
exit(0);
}
} else {
// Automatic mode
await Future.delayed(Duration(seconds: delay));
}
// Try using the transaction that was obtained before the fault/outage
try {
final r = await tx
.execute("SELECT TIMEDIFF(NOW(),UTC_TIMESTAMP) AS 'tz_offset'");
Results result = await r.deStream();
//print(result.map((r) => r.byName('tz_offset')));
print('$runTime: query succeeded');
await tx.commit();
} catch (e) {
print("$runTime: query exception (${e.runtimeType}): $e");
}
await conn.close();
} catch (e) {
print('$runTime: no connection/transaction: $e');
}
if (continueMode) {
// Continuous mode: give a chance for the database to come back
// before starting the next run.
if (delay == null) {
// Interactive mode
stdout.write("Start the database and press enter to continue... ");
var line = stdin.readLineSync().trim().toLowerCase();
if (line == 'q') {
exit(0);
}
} else {
// Automatic mode
await Future.delayed(Duration(seconds: delay));
}
}
} while (continueMode);
}