Implement Service Refactoring

<UserStory> 1954: Implement Service Refactoring </UserStory>

UserStory #1954

<Changes>
1. Refactored notification handling to persist notifications directly in the datastore instead of maintaining notification collections within User objects.
2. Removed recipient User pointer dependencies from Notification and retained recipient user identification through recipientUserId.
3. Implemented generic observer persistence support in DataStore with shared helper methods for loading and saving observer subscriptions.
4. Added datastore-backed observer management for ServiceManagementService, PaymentManagementService, and InventoryManagementService.
5. Updated attach() and detach() operations to load, modify, and persist observer subscriptions using shared memory mappings.
6. Refactored sendNotification() implementations to create and persist Notification records directly to the datastore for subscribed observers.
7. Updated UserManagementService notification retrieval and deletion logic to operate on datastore notification records filtered by recipient user ID.
8. Removed notification ownership and observer-specific notification APIs from User and Observer classes.
9. Added configurable shared memory growth factor support and updated mapping expansion logic to use centralized configuration values.
10. Removed obsolete NotificationManagementService implementation and updated project configuration references.
11. Added DataStoreLockGuard integration for observer and notification persistence operations to ensure synchronized datastore access.
</Changes>

<Test>
N/A
</Test>

<Review>
Sreeja Reghukumar, please review
</Review>
This commit is contained in:
2026-06-12 19:23:56 +05:30
parent 79d6b47aa8
commit edd0c60e40
17 changed files with 186 additions and 210 deletions
@@ -230,20 +230,6 @@ util::Map<std::string, TrackedRecord<User>>& DataStore::getUsers()
{
auto users = loadRecords<User, SerializedUser>(m_users);
refreshCache(m_userCache, users);
auto& notifications = getNotifications();
int numberOfNotifications = m_notificationCache.getSize();
for (int index = 0; index < numberOfNotifications; index++)
{
Notification* notification = notifications.getValueAt(index).data;
const std::string& recipientUserId = notification->getRecipientUserId();
int userIndex = m_userCache.find(recipientUserId);
if (userIndex == -1)
{
throw std::runtime_error("Invalid recipient user ID");
}
User* user = m_userCache.getValueAt(userIndex).data;
user->addNotification(notification);
}
return m_userCache;
}
@@ -340,6 +326,37 @@ util::Map<std::string, TrackedRecord<Invoice>>& DataStore::getInvoices()
return m_invoiceCache;
}
/*
Function: getObservers
Description: Retrieves observer records from the specified observer mapping
and resolves them to User objects.
Parameters:
- mapping: Observer mapping to read from
Returns:
- util::Map<std::string, User*>: Collection of observer records
Throws:
- std::runtime_error if an observer references an invalid user ID
*/
util::Map<std::string, User*> DataStore::getObservers(MappingInfo& mapping)
{
auto& users = getUsers();
util::Map<std::string, User*> observers;
SharedMemory::ensureLatestMapping(mapping);
size_t recordCount = SharedMemory::getRecordCount(mapping);
for (size_t index = 0; index < recordCount; index++)
{
const SerializedObserver* observer = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index));
int userIndex = users.find(observer->id);
if (userIndex == -1)
{
throw std::runtime_error("Invalid observer user ID");
}
User* user = users.getValueAt(userIndex).data;
observers.insert(user->getId(), user);
}
return observers;
}
/*
Function: getServiceManagementObservers
Description: Retrieves all service management observer records from the datastore.
@@ -350,7 +367,7 @@ Returns:
*/
util::Map<std::string, User*> DataStore::getServiceManagementObservers()
{
return util::Map<std::string, User*>();
return getObservers(m_serviceManagementObservers);
}
/*
@@ -363,7 +380,7 @@ Returns:
*/
util::Map<std::string, User*> DataStore::getPaymentManagementObservers()
{
return util::Map<std::string, User*>();
return getObservers(m_paymentManagementObservers);
}
/*
@@ -376,7 +393,7 @@ Returns:
*/
util::Map<std::string, User*> DataStore::getInventoryManagementObservers()
{
return util::Map<std::string, User*>();
return getObservers(m_inventoryManagementObservers);
}
/*
@@ -390,7 +407,6 @@ Returns:
void DataStore::saveUsers()
{
saveRecords<User, SerializedUser>(m_users, m_userCache);
saveNotifications();
}
/*
@@ -478,16 +494,49 @@ void DataStore::saveInvoices()
{
}
/*
Function: saveObservers
Description: Persists observer records to the specified observer mapping.
Parameters:
- mapping: MappingInfo&, observer mapping to save to
- observers: util::Map<std::string, User*>&, collection of observer records
Returns:
- None
*/
void DataStore::saveObservers(MappingInfo& mapping, util::Map<std::string, User*>& observers)
{
size_t observerCount = static_cast<size_t>(observers.getSize());
size_t capacity = config::file::INITIAL_CAPACITY;
while (capacity < observerCount)
{
capacity *= config::file::GROWTH_FACTOR;
}
if (!SharedMemory::resizeMapping(mapping, capacity))
{
throw std::runtime_error("Failed to resize observer mapping");
}
SharedMemory::setRecordCount(mapping, observerCount);
for (size_t index = 0; index < observerCount; index++)
{
SerializedObserver serializedObserver;
User* user = observers.getValueAt(static_cast<int>(index));
strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str());
SerializedObserver* destination = static_cast<SerializedObserver*>(SharedMemory::getRecordAddress(mapping, index));
*destination = serializedObserver;
}
}
/*
Function: saveServiceManagementObservers
Description: Persists all service management observer records to the datastore.
Parameters:
- observers: util::Map<std::string, TrackedRecord<std::string>>&, collection of observer records
- observers: util::Map<std::string, User*>&, collection of observer records
Returns:
- None
*/
void DataStore::saveServiceManagementObservers(util::Map<std::string, User*>& observers)
{
saveObservers(m_serviceManagementObservers, observers);
}
/*
@@ -500,6 +549,7 @@ Returns:
*/
void DataStore::savePaymentManagementObservers(util::Map<std::string, User*>& observers)
{
saveObservers(m_paymentManagementObservers, observers);
}
/*
@@ -512,6 +562,7 @@ Returns:
*/
void DataStore::saveInventoryManagementObservers(util::Map<std::string, User*>& observers)
{
saveObservers(m_inventoryManagementObservers, observers);
}
/*