41
41
import com .google .common .collect .BoundType ;
42
42
import com .google .common .collect .Range ;
43
43
import com .google .common .collect .Sets ;
44
+
45
+ import accord .coordinate .AbstractCoordination ;
46
+ import accord .coordinate .Coordination ;
47
+ import accord .coordinate .Coordinations ;
48
+ import accord .coordinate .PrepareRecovery ;
49
+ import accord .coordinate .tracking .AbstractTracker ;
50
+ import accord .utils .SortedListMap ;
44
51
import org .apache .cassandra .cql3 .Operator ;
45
52
import org .apache .cassandra .db .EmptyIterators ;
46
53
import org .apache .cassandra .db .filter .ClusteringIndexFilter ;
57
64
import accord .coordinate .FetchData ;
58
65
import accord .coordinate .FetchRoute ;
59
66
import accord .coordinate .MaybeRecover ;
60
- import accord .coordinate .RecoverWithRoute ;
61
67
import accord .impl .CommandChange ;
62
68
import accord .impl .progresslog .DefaultProgressLog ;
63
69
import accord .impl .progresslog .TxnStateKind ;
151
157
152
158
public class AccordDebugKeyspace extends VirtualKeyspace
153
159
{
160
+ public static final String COORDINATIONS = "coordinations" ;
161
+ public static final String EXECUTORS = "executors" ;
154
162
public static final String COMMANDS_FOR_KEY = "commands_for_key" ;
155
163
public static final String COMMANDS_FOR_KEY_UNMANAGED = "commands_for_key_unmanaged" ;
156
164
public static final String DURABILITY_SERVICE = "durability_service" ;
@@ -173,6 +181,8 @@ public class AccordDebugKeyspace extends VirtualKeyspace
173
181
private AccordDebugKeyspace ()
174
182
{
175
183
super (VIRTUAL_ACCORD_DEBUG , List .of (
184
+ new ExecutorsTable (),
185
+ new CoordinationsTable (),
176
186
new CommandsForKeyTable (),
177
187
new CommandsForKeyUnmanagedTable (),
178
188
new DurabilityServiceTable (),
@@ -192,6 +202,118 @@ private AccordDebugKeyspace()
192
202
));
193
203
}
194
204
205
+ // TODO (desired): human readable packed key tracker (but requires loading Txn, so might be preferable to only do conditionally)
206
+ public static final class ExecutorsTable extends AbstractVirtualTable
207
+ {
208
+ private ExecutorsTable ()
209
+ {
210
+ super (parse (VIRTUAL_ACCORD_DEBUG , EXECUTORS ,
211
+ "Accord Executor State" ,
212
+ "CREATE TABLE %s (\n " +
213
+ " executor_id int,\n " +
214
+ " status text,\n " +
215
+ " position int,\n " +
216
+ " unique_position int,\n " +
217
+ " description text,\n " +
218
+ " command_store_id int,\n " +
219
+ " txn_id 'TxnIdUtf8Type',\n " +
220
+ " txn_id_additional 'TxnIdUtf8Type',\n " +
221
+ " keys text,\n " +
222
+ " keysLoad text,\n " +
223
+ " keysLoadFor text,\n " +
224
+ " PRIMARY KEY (executor_id, status, position, unique_position)" +
225
+ ')' , UTF8Type .instance ));
226
+ }
227
+
228
+ @ Override
229
+ public DataSet data ()
230
+ {
231
+ AccordCommandStores commandStores = (AccordCommandStores ) AccordService .instance ().node ().commandStores ();
232
+ SimpleDataSet ds = new SimpleDataSet (metadata ());
233
+
234
+ for (AccordExecutor executor : commandStores .executors ())
235
+ {
236
+ int uniquePos = 0 ;
237
+ int executorId = executor .executorId ();
238
+ AccordExecutor .TaskInfo prev = null ;
239
+ for (AccordExecutor .TaskInfo info : executor .taskSnapshot ())
240
+ {
241
+ if (prev != null && info .status () == prev .status () && info .position () == prev .position ()) ++uniquePos ;
242
+ else uniquePos = 0 ;
243
+ prev = info ;
244
+ PreLoadContext preLoadContext = info .preLoadContext ();
245
+ ds .row (executorId , info .status (), info .position (), uniquePos )
246
+ .column ("description" , info .describe ())
247
+ .column ("command_store_id" , info .commandStoreId ())
248
+ .column ("txn_id" , preLoadContext == null ? null : preLoadContext .primaryTxnId ())
249
+ .column ("txn_id_additional" , preLoadContext == null ? null : preLoadContext .additionalTxnId ())
250
+ .column ("keys" , preLoadContext == null ? null : preLoadContext .keys ())
251
+ .column ("keysLoad" , preLoadContext == null ? null : preLoadContext .loadKeys ())
252
+ .column ("keysLoadFor" , preLoadContext == null ? null : preLoadContext .loadKeysFor ())
253
+ ;
254
+ }
255
+ }
256
+ return ds ;
257
+ }
258
+ }
259
+
260
+ // TODO (desired): human readable packed key tracker (but requires loading Txn, so might be preferable to only do conditionally)
261
+ public static final class CoordinationsTable extends AbstractVirtualTable
262
+ {
263
+ private CoordinationsTable ()
264
+ {
265
+ super (parse (VIRTUAL_ACCORD_DEBUG , COORDINATIONS ,
266
+ "Accord Coordination State" ,
267
+ "CREATE TABLE %s (\n " +
268
+ " txn_id int,\n " +
269
+ " kind text,\n " +
270
+ " coordination_id int,\n " +
271
+ " description text,\n " +
272
+ " nodes text,\n " +
273
+ " nodes_inflight text,\n " +
274
+ " nodes_contacted text,\n " +
275
+ " participants text,\n " +
276
+ " replies text,\n " +
277
+ " tracker text,\n " +
278
+ " PRIMARY KEY (txn_id, kind, coordination_id)" +
279
+ ')' , UTF8Type .instance ));
280
+ }
281
+
282
+ @ Override
283
+ public DataSet data ()
284
+ {
285
+ Coordinations coordinations = AccordService .instance ().node ().coordinations ();
286
+ SimpleDataSet ds = new SimpleDataSet (metadata ());
287
+ for (Coordination c : coordinations )
288
+ {
289
+ ds .row (c .txnId (), c .kind ().toString (), c .coordinationId ())
290
+ .column ("nodes" , toStringOrNull (c .nodes ()))
291
+ .column ("nodes_inflight" , toStringOrNull (c .inflight ()))
292
+ .column ("nodes_contacted" , toStringOrNull (c .contacted ()))
293
+ .column ("description" , c .describe ())
294
+ .column ("participants" , toStringOrNull (c .scope ()))
295
+ .column ("replies" , summarise (c .replies ()))
296
+ .column ("tracker" , summarise (c .tracker ()));
297
+ }
298
+ return ds ;
299
+ }
300
+
301
+ private static String summarise (@ Nullable SortedListMap <Node .Id , ?> replies )
302
+ {
303
+ if (replies == null )
304
+ return null ;
305
+ return AbstractCoordination .summariseReplies (replies , 60 );
306
+ }
307
+
308
+ private static String summarise (@ Nullable AbstractTracker <?> tracker )
309
+ {
310
+ if (tracker == null )
311
+ return null ;
312
+ return tracker .summariseTracker ();
313
+ }
314
+ }
315
+
316
+
195
317
// TODO (desired): don't report null as "null"
196
318
public static final class CommandsForKeyTable extends AbstractVirtualTable implements AbstractVirtualTable .DataSet
197
319
{
@@ -529,7 +651,7 @@ public DataSet data()
529
651
private static void addRow (SimpleDataSet ds , int executorId , String scope , AccordCache .ImmutableStats stats )
530
652
{
531
653
ds .row (executorId , scope )
532
- .column ("queries" , stats .queries )
654
+ .column ("queries" , stats .hits + stats . misses )
533
655
.column ("hits" , stats .hits )
534
656
.column ("misses" , stats .misses );
535
657
}
@@ -1365,7 +1487,7 @@ private void recover(TxnId txnId, @Nullable Route<?> route, AsyncResult.Settable
1365
1487
Node node = AccordService .instance ().node ();
1366
1488
if (Route .isFullRoute (route ))
1367
1489
{
1368
- RecoverWithRoute .recover (node , node .someSequentialExecutor (), txnId , NotKnownToBeInvalid , (FullRoute <?>) route , null , LatentStoreSelector .standard (), (success , fail ) -> {
1490
+ PrepareRecovery .recover (node , node .someSequentialExecutor (), txnId , NotKnownToBeInvalid , (FullRoute <?>) route , null , LatentStoreSelector .standard (), (success , fail ) -> {
1369
1491
if (fail != null ) result .setFailure (fail );
1370
1492
else result .setSuccess (null );
1371
1493
}, node .agent ().trace (txnId , RECOVER ));
0 commit comments