Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One more fix for #1499 - protected mongocConnectionGet with a semaphore #1549

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading