starts a locking flow before commiting changes Locking flow: 1. lock GIL 2. open key with `write` flag 3. graph R/W lock with write flag since 2PL protocal is implemented, the method returns true if it managed to achieve locks in this call or a previous call in case that the locks are already locked, there will be no attempt to lock them again this method returns false if the key has changed from
| 343 | // them again this method returns false if the key has changed |
| 344 | // from the current graph, and sets the relevant error message |
| 345 | bool QueryCtx_LockForCommit(void) { |
| 346 | QueryCtx *ctx = _QueryCtx_GetCreateCtx(); |
| 347 | if(ctx->internal_exec_ctx.locked_for_commit) return true; |
| 348 | |
| 349 | // lock GIL |
| 350 | RedisModuleCtx *redis_ctx = ctx->global_exec_ctx.redis_ctx; |
| 351 | GraphContext *gc = ctx->gc; |
| 352 | RedisModuleString *graphID = RedisModule_CreateString(redis_ctx, gc->graph_name, |
| 353 | strlen(gc->graph_name)); |
| 354 | _QueryCtx_ThreadSafeContextLock(ctx); |
| 355 | |
| 356 | // open key and verify |
| 357 | RedisModuleKey *key = RedisModule_OpenKey(redis_ctx, graphID, REDISMODULE_WRITE); |
| 358 | RedisModule_FreeString(redis_ctx, graphID); |
| 359 | if(RedisModule_KeyType(key) == REDISMODULE_KEYTYPE_EMPTY) { |
| 360 | ErrorCtx_SetError("Encountered an empty key when opened key %s", ctx->gc->graph_name); |
| 361 | goto clean_up; |
| 362 | } |
| 363 | if(RedisModule_ModuleTypeGetType(key) != GraphContextRedisModuleType) { |
| 364 | ErrorCtx_SetError("Encountered a non-graph value type when opened key %s", ctx->gc->graph_name); |
| 365 | goto clean_up; |
| 366 | |
| 367 | } |
| 368 | if(gc != RedisModule_ModuleTypeGetValue(key)) { |
| 369 | ErrorCtx_SetError("Encountered different graph value when opened key %s", ctx->gc->graph_name); |
| 370 | goto clean_up; |
| 371 | } |
| 372 | ctx->internal_exec_ctx.key = key; |
| 373 | |
| 374 | // acquire graph write lock |
| 375 | Graph_AcquireWriteLock(gc->g); |
| 376 | ctx->internal_exec_ctx.locked_for_commit = true; |
| 377 | |
| 378 | return true; |
| 379 | |
| 380 | clean_up: |
| 381 | // free key handle |
| 382 | RedisModule_CloseKey(key); |
| 383 | |
| 384 | // unlock GIL |
| 385 | _QueryCtx_ThreadSafeContextUnlock(ctx); |
| 386 | |
| 387 | // if there is a break point for runtime exception, raise it, otherwise return false |
| 388 | ErrorCtx_RaiseRuntimeException(NULL); |
| 389 | return false; |
| 390 | } |
| 391 | |
| 392 | static void _QueryCtx_UnlockCommit |
| 393 | ( |
no test coverage detected