Skip to content

Commit

Permalink
One more fix for #1499 - protected mongocConnectionGet with a semaphore
Browse files Browse the repository at this point in the history
  • Loading branch information
kzangeli committed Feb 8, 2024
1 parent 88be9a6 commit 8a22ea7
Show file tree
Hide file tree
Showing 46 changed files with 99 additions and 149 deletions.
1 change: 1 addition & 0 deletions src/lib/orionld/common/orionldState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ bool entityMapsEnabled = false;
mongoc_uri_t* mongocUri;
mongoc_client_pool_t* mongocPool;
sem_t mongocContextsSem;
sem_t mongocConnectionSem;
char mongocServerVersion[128];
char postgresServerVersion[128];

Expand Down
1 change: 1 addition & 0 deletions src/lib/orionld/common/orionldState.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ extern mongoc_collection_t* mongoRegistrationsCollectionP; // Deprecated
extern mongoc_uri_t* mongocUri;
extern mongoc_client_pool_t* mongocPool;
extern sem_t mongocContextsSem;
extern sem_t mongocConnectionSem;
extern char mongocServerVersion[128];
extern char postgresServerVersion[128];

Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocAttributeDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ extern "C"
//
bool mongocAttributeDelete(const char* entityId, const char* attrName)
{
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_t selector;
bson_init(&selector);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocAttributeReplace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ extern "C"
//
bool mongocAttributeReplace(const char* entityId, KjNode* dbAttrP, char** detailP)
{
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_t selector;
bson_init(&selector);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocAttributesAdd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ bool mongocAttributesAdd
bool singleAttribute
)
{
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_t selector;
bson_init(&selector);
Expand Down
32 changes: 31 additions & 1 deletion src/lib/orionld/mongoc/mongocConnectionGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
* Author: Ken Zangelin
*/
#include <unistd.h> // NULL
#include <semaphore.h> // sem_wait, sem_post
#include <mongoc/mongoc.h> // mongoc driver

#include "orionld/common/orionldState.h" // orionldState, mongocPool
#include "orionld/types/OrionldTenant.h" // OrionldTenant
#include "orionld/mongoc/mongocConnectionGet.h" // Own interface


Expand All @@ -34,8 +36,36 @@
//
// mongocConnectionGet -
//
void mongocConnectionGet(void)
void mongocConnectionGet(OrionldTenant* tenantP, DbCollection dbCollection)
{
sem_wait(&mongocConnectionSem);

if (orionldState.mongoc.client == NULL)
orionldState.mongoc.client = mongoc_client_pool_pop(mongocPool);

if ((dbCollection & DbEntities) == DbEntities)
{
if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, tenantP->mongoDbName, "entities");
}

if ((dbCollection & DbSubscriptions) == DbSubscriptions)
{
if (orionldState.mongoc.subscriptionsP == NULL)
orionldState.mongoc.subscriptionsP = mongoc_client_get_collection(orionldState.mongoc.client, tenantP->mongoDbName, "csubs");
}

if ((dbCollection & DbRegistrations) == DbRegistrations)
{
if (orionldState.mongoc.registrationsP == NULL)
orionldState.mongoc.registrationsP = mongoc_client_get_collection(orionldState.mongoc.client, tenantP->mongoDbName, "registrations");
}

if ((dbCollection & DbContexts) == DbContexts)
{
if (orionldState.mongoc.contextsP == NULL)
orionldState.mongoc.contextsP = mongoc_client_get_collection(orionldState.mongoc.client, "orionld", "contexts");
}

sem_post(&mongocConnectionSem);
}
18 changes: 17 additions & 1 deletion src/lib/orionld/mongoc/mongocConnectionGet.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,29 @@
*
* Author: Ken Zangelin
*/
#include "orionld/types/OrionldTenant.h" // OrionldTenant



// -----------------------------------------------------------------------------
//
// DbCollection - move to orionld/types/DbCollection.h
//
typedef enum DbCollection
{
DbNone = 1,
DbEntities = 2,
DbSubscriptions = 4,
DbRegistrations = 8,
DbContexts = 16
} DbCollection;



// -----------------------------------------------------------------------------
//
// mongocConnectionGet -
//
extern void mongocConnectionGet(void);
extern void mongocConnectionGet(OrionldTenant* tenantP, DbCollection dbCollection);

#endif // SRC_LIB_ORIONLD_MONGOC_MONGOCCONNECTIONGET_H_
6 changes: 2 additions & 4 deletions src/lib/orionld/mongoc/mongocContextCacheDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*
* Author: Ken Zangelin
*/
#include <semaphore.h> // sem_wait, sem_post
#include <bson/bson.h> // bson_t, ...
#include <mongoc/mongoc.h> // mongoc driver

Expand All @@ -46,10 +47,7 @@ void mongocContextCacheDelete(const char* id)
{
bson_t selector;

mongocConnectionGet();

if (orionldState.mongoc.contextsP == NULL)
orionldState.mongoc.contextsP = mongoc_client_get_collection(orionldState.mongoc.client, "orionld", "contexts");
mongocConnectionGet(NULL, DbContexts);

bson_init(&selector);
bson_append_utf8(&selector, "_id", 3, id, -1);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocContextCacheGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@ KjNode* mongocContextCacheGet(void)
bson_t* query = bson_new(); // Empty - to find all the contexts in the DB
KjNode* contextArray = kjArray(orionldState.kjsonP, NULL);

mongocConnectionGet();

if (orionldState.mongoc.contextsP == NULL)
orionldState.mongoc.contextsP = mongoc_client_get_collection(orionldState.mongoc.client, "orionld", "contexts");
mongocConnectionGet(NULL, DbContexts);

sem_wait(&mongocContextsSem);

Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocContextCachePersist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ void mongocContextCachePersist(KjNode* contextObject)

mongocKjTreeToBson(contextObject, &bson);

mongocConnectionGet();

if (orionldState.mongoc.contextsP == NULL)
orionldState.mongoc.contextsP = mongoc_client_get_collection(orionldState.mongoc.client, "orionld", "contexts");
mongocConnectionGet(NULL, DbContexts);

sem_wait(&mongocContextsSem);

Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntitiesDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ extern "C"
//
bool mongocEntitiesDelete(KjNode* entityIdArray)
{
mongocConnectionGet(); // mongocConnectionGet(MONGO_ENTITIES) - do the mongoc_client_get_collection also

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

mongoc_bulk_operation_t* bulkP;

Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntitiesExist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,7 @@ KjNode* mongocEntitiesExist(KjNode* entityIdArray, bool entityType)
bson_append_document(&options, "projection", 10, &projection);
bson_destroy(&projection);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

mongoCursorP = mongoc_collection_find_with_opts(orionldState.mongoc.entitiesP, &mongoFilter, &options, readPrefs);
bson_destroy(&options);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntitiesGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,7 @@ KjNode* mongocEntitiesGet(char** fieldV, int fields, bool entityIdPresent)
bson_t mongoFilter;
bson_init(&mongoFilter);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

//
// Run the query
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntitiesQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,7 @@ KjNode* mongocEntitiesQuery
bson_append_document(&options, "projection", 10, &projection);
bson_destroy(&projection);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

// semTake(&mongoEntitiesSem);

Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntitiesQuery2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,7 @@ KjNode* mongocEntitiesQuery2
bson_append_document(&options, "projection", 10, &projection);
bson_destroy(&projection);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

// count?
if (orionldState.uriParams.count == true)
Expand Down
6 changes: 1 addition & 5 deletions src/lib/orionld/mongoc/mongocEntitiesUpsert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,9 @@ extern "C"
//
bool mongocEntitiesUpsert(KjNode* createArrayP, KjNode* updateArrayP)
{
mongocConnectionGet(); // mongocConnectionGet(MONGO_ENTITIES) - do the mongoc_client_get_collection also

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

mongoc_bulk_operation_t* bulkP;

bulkP = mongoc_collection_create_bulk_operation_with_opts(orionldState.mongoc.entitiesP, NULL);

if (createArrayP != NULL)
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ extern "C"
//
bool mongocEntityDelete(const char* entityId, char** detailP)
{
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "csubs");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_t selector;
bson_error_t error;
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ KjNode* mongocEntityGet(const char* entityId, const char** projectionV, bool inc
//
// Get the connection
//
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

//
// Perform the query
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityInsert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ bool mongocEntityInsert(KjNode* dbEntityP, const char* entityId)
bson_t document;
bson_t reply;

mongocConnectionGet(); // mongocConnectionGet(MONGO_ENTITIES) - do the mongoc_client_get_collection also

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_init(&document);
bson_init(&reply);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@ KjNode* mongocEntityLookup(const char* entityId, const char* entityType, StringA
if (entityType != NULL)
bson_append_utf8(&mongoFilter, "_id.type", 8, entityType, -1);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

//
// Projection (will be added to if attrList != NULL)
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityReplace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ bool mongocEntityReplace(KjNode* dbEntityP, const char* entityId)
bson_t replacement;
bson_t reply;

mongocConnectionGet(); // mongocConnectionGet(MONGO_ENTITIES) - do the mongoc_client_get_collection also

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_init(&selector);
bson_init(&replacement);
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityRetrieve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,7 @@ KjNode* mongocEntityRetrieve
bson_init(&mongoFilter);
bson_append_utf8(&mongoFilter, "_id.id", 6, entityId, -1);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

//
// Run the query
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityTypeGet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ KjNode* mongocEntityTypeGet(OrionldProblemDetails* pdP, const char* typeLongName

mongoc_read_prefs_t* readPrefs = mongoc_read_prefs_new(MONGOC_READ_NEAREST);

mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

mongoc_cursor_t* mongoCursorP;
mongoCursorP = mongoc_collection_find_with_opts(orionldState.mongoc.entitiesP, &mongoFilter, &options, readPrefs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,7 @@ KjNode* mongocEntityTypesFromRegistrationsGet(bool details)
bson_destroy(&projection);

// Connection
mongocConnectionGet();

if (orionldState.mongoc.registrationsP == NULL)
orionldState.mongoc.registrationsP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "registrations");
mongocConnectionGet(orionldState.tenantP, DbRegistrations);

//
// Run the query
Expand Down
5 changes: 1 addition & 4 deletions src/lib/orionld/mongoc/mongocEntityUpdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,7 @@ static bool patchApply
//
bool mongocEntityUpdate(const char* entityId, KjNode* patchTree)
{
mongocConnectionGet();

if (orionldState.mongoc.entitiesP == NULL)
orionldState.mongoc.entitiesP = mongoc_client_get_collection(orionldState.mongoc.client, orionldState.tenantP->mongoDbName, "entities");
mongocConnectionGet(orionldState.tenantP, DbEntities);

bson_t selector;
bson_init(&selector);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/mongoc/mongocGeoIndexCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool mongocGeoIndexCreate(OrionldTenant* tenantP, const char* attrLongName)
bson_init(&key);
BSON_APPEND_UTF8(&key, indexPath, "2dsphere");

mongocConnectionGet();
mongocConnectionGet(NULL, DbNone);

mongoc_database_t* dbP = mongoc_client_get_database(orionldState.mongoc.client, tenantP->mongoDbName);
char* indexName = mongoc_collection_keys_to_index_string(&key);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/mongoc/mongocGeoIndexInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ bool mongocGeoIndexInit(void)
//
// DB Connection
//
mongocConnectionGet();
mongocConnectionGet(NULL, DbNone);

//
// Loop over all tenants
Expand Down
2 changes: 1 addition & 1 deletion src/lib/orionld/mongoc/mongocIdIndexCreate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ bool mongocIdIndexCreate(OrionldTenant* tenantP)
bson_init(&key);
BSON_APPEND_INT32(&key, "_id.id", 1);

mongocConnectionGet();
mongocConnectionGet(NULL, DbNone);

mongoc_database_t* dbP = mongoc_client_get_database(orionldState.mongoc.client, tenantP->mongoDbName);
char* indexName = mongoc_collection_keys_to_index_string(&key);
Expand Down
5 changes: 5 additions & 0 deletions src/lib/orionld/mongoc/mongocInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ void mongocInit
//
sem_init(&mongocContextsSem, 0, 1); // 0: shared between threads of the same process. 1: free to be taken

//
// Semaphore for getting a connection/collection for mongo
//
sem_init(&mongocConnectionSem, 0, 1); // 0: shared between threads of the same process. 1: free to be taken

if (mongocTenantsGet() == false)
LM_X(1, ("Unable to extract tenants from the database - fatal error"));

Expand Down
Loading

0 comments on commit 8a22ea7

Please sign in to comment.