@@ -346,17 +346,19 @@ void Countly::_changeDeviceIdWithoutMerge(const std::string &value) {
346346
347347 // send all event to server and end current session of old user
348348 flushEvents ();
349- if (began_session) {
349+ if (!configuration-> manualSessionControl ) {
350350 endSession ();
351- mutex->lock ();
352- session_params[" device_id" ] = value;
353- mutex->unlock ();
351+ }
352+
353+ mutex->lock ();
354+ session_params[" device_id" ] = value;
355+ mutex->unlock ();
356+
357+ // start a new session for new user
358+ if (!configuration->manualSessionControl ){
354359 beginSession ();
355- } else {
356- mutex->lock ();
357- session_params[" device_id" ] = value;
358- mutex->unlock ();
359360 }
361+
360362}
361363#pragma endregion Device Id
362364
@@ -401,7 +403,7 @@ void Countly::start(const std::string &app_key, const std::string &host, int por
401403 log (LogLevel::INFO, " [Countly][start] '_WIN32' is not defined" );
402404#endif
403405
404- enable_automatic_session = start_thread;
406+ enable_automatic_session = start_thread && !configuration-> manualSessionControl ;
405407 start_thread = true ;
406408
407409 if (port < 0 || port > 65535 ) {
@@ -436,9 +438,11 @@ void Countly::start(const std::string &app_key, const std::string &host, int por
436438
437439 if (!running) {
438440
439- mutex->unlock ();
440- beginSession ();
441- mutex->lock ();
441+ if (!configuration->manualSessionControl ){
442+ mutex->unlock ();
443+ beginSession ();
444+ mutex->lock ();
445+ }
442446
443447 if (start_thread) {
444448 stop_thread = false ;
@@ -465,7 +469,7 @@ void Countly::startOnCloud(const std::string &app_key) {
465469
466470void Countly::stop () {
467471 _deleteThread ();
468- if (began_session ) {
472+ if (!configuration-> manualSessionControl ) {
469473 endSession ();
470474 }
471475}
@@ -607,8 +611,16 @@ bool Countly::attemptSessionUpdateEQ() {
607611 return false ;
608612 }
609613#endif
610-
611- return !updateSession ();
614+ bool result;
615+ if (!configuration->manualSessionControl ){
616+ result = !updateSession ();
617+ } else {
618+ log (LogLevel::WARNING, " [Countly][attemptSessionUpdateEQ] SDK is in manual session control mode. Please start a session first." );
619+ result = false ;
620+ }
621+
622+ packEvents ();
623+ return result;
612624}
613625
614626void Countly::clearEQInternal () {
@@ -670,6 +682,7 @@ bool Countly::beginSession() {
670682 log (LogLevel::INFO, " [Countly][beginSession]" );
671683 if (began_session) {
672684 mutex->unlock ();
685+ log (LogLevel::DEBUG, " [Countly][beginSession] Session is already active." );
673686 return true ;
674687 }
675688
@@ -725,15 +738,42 @@ bool Countly::updateSession() {
725738 mutex->lock ();
726739 if (!began_session) {
727740 mutex->unlock ();
741+ if (configuration->manualSessionControl ){
742+ log (LogLevel::WARNING, " [Countly][updateSession] SDK is in manual session control mode and there is no active session. Please start a session first." );
743+ return false ;
744+ }
728745 if (!beginSession ()) {
729746 // if beginSession fails, we should not try to update session
730747 return false ;
731748 }
732749 mutex->lock ();
733750 began_session = true ;
734751 }
752+
753+ mutex->unlock ();
754+ auto duration = std::chrono::duration_cast<std::chrono::seconds>(getSessionDuration ());
755+ mutex->lock ();
735756
736- // events array
757+ // report session duration if it is greater than the configured session duration value
758+ if (duration.count () >= configuration->sessionDuration ) {
759+ log (LogLevel::DEBUG, " [Countly][updateSession] sending session update." );
760+ std::map<std::string, std::string> data = {{" app_key" , session_params[" app_key" ].get <std::string>()}, {" device_id" , session_params[" device_id" ].get <std::string>()}, {" session_duration" , std::to_string (duration.count ())}};
761+ requestModule->addRequestToQueue (data);
762+
763+ last_sent_session_request += duration;
764+ }
765+ } catch (const std::system_error &e) {
766+ std::ostringstream log_message;
767+ log_message << " update session, error: " << e.what ();
768+ log (LogLevel::FATAL, log_message.str ());
769+ }
770+ mutex->unlock ();
771+ return true ;
772+ }
773+
774+ void Countly::packEvents () {
775+ try {
776+ // events array
737777 nlohmann::json events = nlohmann::json::array ();
738778 std::string event_ids;
739779 mutex->unlock ();
@@ -754,20 +794,7 @@ bool Countly::updateSession() {
754794 } else {
755795 log (LogLevel::DEBUG, " [Countly][updateSession] EQ empty." );
756796 }
757- mutex->unlock ();
758- auto duration = std::chrono::duration_cast<std::chrono::seconds>(getSessionDuration ());
759- mutex->lock ();
760-
761- // report session duration if it is greater than the configured session duration value
762- if (duration.count () >= configuration->sessionDuration ) {
763- log (LogLevel::DEBUG, " [Countly][updateSession] sending session update." );
764- std::map<std::string, std::string> data = {{" app_key" , session_params[" app_key" ].get <std::string>()}, {" device_id" , session_params[" device_id" ].get <std::string>()}, {" session_duration" , std::to_string (duration.count ())}};
765- requestModule->addRequestToQueue (data);
766-
767- last_sent_session_request += duration;
768- }
769-
770- // report events if there are any to request queue
797+ // report events if there are any to request queue
771798 if (!no_events) {
772799 sendEventsToRQ (events);
773800 }
@@ -788,9 +815,9 @@ bool Countly::updateSession() {
788815 log (LogLevel::FATAL, log_message.str ());
789816 }
790817 mutex->unlock ();
791- return true ;
792818}
793819
820+
794821void Countly::sendEventsToRQ (const nlohmann::json &events) {
795822 log (LogLevel::DEBUG, " [Countly][sendEventsToRQ] Sending events to RQ." );
796823 std::map<std::string, std::string> data = {{" app_key" , session_params[" app_key" ].get <std::string>()}, {" device_id" , session_params[" device_id" ].get <std::string>()}, {" events" , events.dump ()}};
@@ -799,6 +826,10 @@ void Countly::sendEventsToRQ(const nlohmann::json &events) {
799826
800827bool Countly::endSession () {
801828 log (LogLevel::INFO, " [Countly][endSession]" );
829+ if (!began_session) {
830+ log (LogLevel::DEBUG, " [Countly][endSession] There is no active session to end." );
831+ return true ;
832+ }
802833 const std::chrono::system_clock::time_point now = Countly::getTimestamp ();
803834 const auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch ());
804835 const auto duration = std::chrono::duration_cast<std::chrono::seconds>(getSessionDuration (now));
@@ -1127,6 +1158,7 @@ void Countly::updateLoop() {
11271158 if (enable_automatic_session) {
11281159 updateSession ();
11291160 }
1161+ packEvents ();
11301162 requestModule->processQueue (mutex);
11311163 }
11321164 mutex->lock ();
0 commit comments