| 465 | } |
| 466 | |
| 467 | static PythonRequirementCtx* PythonRequirementCtx_Create(const char* requirement){ |
| 468 | #define RAND_SIZE 10 |
| 469 | char rand[RAND_SIZE + 1]; |
| 470 | RedisModule_GetRandomHexChars(rand, RAND_SIZE); |
| 471 | rand[RAND_SIZE] = '\0'; |
| 472 | |
| 473 | // first lets create basePath |
| 474 | int exitCode = RedisGears_ExecuteCommand(NULL, "notice", "mkdir -p '%s/%s_%s'", venvDir, requirement, rand); |
| 475 | if(exitCode != 0){ |
| 476 | return NULL; |
| 477 | } |
| 478 | |
| 479 | PythonRequirementCtx* ret = RG_ALLOC(sizeof(*ret)); |
| 480 | ret->installName = RG_STRDUP(requirement); |
| 481 | RedisGears_ASprintf(&ret->basePath, "%s/%s_%s", venvDir, ret->installName, rand); |
| 482 | ret->wheels = array_new(char*, 10); |
| 483 | // refCount is starting from 2, one hold by RequirementsDict and once by the caller. |
| 484 | // currently we basically never delete requirements so we will know not to reinstall them |
| 485 | // to save time |
| 486 | ret->refCount = 1; |
| 487 | pthread_mutex_init(&ret->installationLock, NULL); |
| 488 | |
| 489 | ret->isInRequirementsDict = false; |
| 490 | |
| 491 | PythonRequirementCtx_VerifyBasePath(ret); |
| 492 | |
| 493 | ret->isInstalled = false; |
| 494 | ret->isDownloaded = false; |
| 495 | |
| 496 | return ret; |
| 497 | } |
| 498 | |
| 499 | typedef struct{ |
| 500 | const char* fileName; |
no test coverage detected