Skip to content

Commit c363fe9

Browse files
dorjesinpopniedzielski
authored andcommitted
startAsync and StopAsync callbacks
Signed-off-by: dorjesinpo <129227380+dorjesinpo@users.noreply.github.com>
1 parent c0f2728 commit c363fe9

19 files changed

Lines changed: 1766 additions & 32 deletions

src/groups/bmq/bmqa/bmqa_abstractsession.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ int AbstractSession::startAsync(
5454
return -1;
5555
}
5656

57+
int AbstractSession::startAsync(
58+
BSLA_MAYBE_UNUSED const StartCallback& callback,
59+
BSLA_MAYBE_UNUSED const bsls::TimeInterval& timeout)
60+
{
61+
// PRECONDITIONS
62+
BSLS_ASSERT_OPT(false && "Method is undefined in base protocol");
63+
64+
return -1;
65+
}
66+
5767
void AbstractSession::stop()
5868
{
5969
// PRECONDITIONS
@@ -66,6 +76,12 @@ void AbstractSession::stopAsync()
6676
BSLS_ASSERT_OPT(false && "Method is undefined in base protocol");
6777
}
6878

79+
void AbstractSession::stopAsync(BSLA_MAYBE_UNUSED const StopCallback& callback)
80+
{
81+
// PRECONDITIONS
82+
BSLS_ASSERT_OPT(false && "Method is undefined in base protocol");
83+
}
84+
6985
void AbstractSession::finalizeStop()
7086
{
7187
// PRECONDITIONS

src/groups/bmq/bmqa/bmqa_abstractsession.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <bmqa_messageproperties.h>
3131
#include <bmqa_openqueuestatus.h>
3232
#include <bmqa_queueid.h>
33+
#include <bmqa_startstatus.h>
34+
#include <bmqa_stopstatus.h>
3335
#include <bmqt_queueoptions.h>
3436
#include <bmqt_uri.h>
3537

@@ -71,6 +73,16 @@ class AbstractSession {
7173
typedef bsl::function<void(const bmqa::CloseQueueStatus& result)>
7274
CloseQueueCallback;
7375

76+
/// An asynchronous session start operation callback
77+
/// that takes as an argument the specified `result`, providing the result
78+
/// of the start operation.
79+
typedef bsl::function<void(const bmqa::StartStatus& result)> StartCallback;
80+
81+
/// An asynchronous session stop operation callback
82+
/// that takes as an argument the specified `result`, providing the result
83+
/// and context of the stop operation.
84+
typedef bsl::function<void(const bmqa::StopStatus& result)> StopCallback;
85+
7486
public:
7587
// CREATORS
7688

@@ -104,6 +116,25 @@ class AbstractSession {
104116
virtual int
105117
startAsync(const bsls::TimeInterval& timeout = bsls::TimeInterval());
106118

119+
/// Connect to the BlazingMQ broker and start the message processing for
120+
/// this `Session`. This method returns without blocking. The result of
121+
/// the operation is communicated to the specified `callback` via a
122+
/// `bmqa::StartStatus`, providing the status of the operation.
123+
/// If the optionally specified `timeout` is not populated, use
124+
/// the one defined in the session options. Return 0 on success (this
125+
/// doesn't imply the session is connected!), or a non-zero value
126+
/// corresponding to the `bmqt::GenericResult::Enum` enum values otherwise.
127+
/// If a non-zero value is returned, the `callback` will *not* be invoked.
128+
/// The behavior is undefined if this method is called on an already
129+
/// started `Session`.
130+
///
131+
/// THREAD: The `callback` will *ALWAYS* be invoked from the EventHandler
132+
/// thread(s) (or if a SessionEventHandler was not specified, from
133+
/// the thread invoking `nextEvent`).
134+
virtual int
135+
startAsync(const StartCallback& callback,
136+
const bsls::TimeInterval& timeout = bsls::TimeInterval());
137+
107138
/// Gracefully disconnect from the BlazingMQ broker and stop the
108139
/// operation of this `Session`. This method blocks waiting for all
109140
/// already invoked event handlers to exit and all session-related
@@ -119,6 +150,18 @@ class AbstractSession {
119150
/// finished. No method may be used after this method returns.
120151
virtual void stopAsync();
121152

153+
/// Disconnect from the BlazingMQ broker and stop the operation of this
154+
/// `Session`. This method returns without blocking and neither enforce
155+
/// nor waits for any already started session-related operation to be
156+
/// finished. The result of the operation is communicated to the specified
157+
/// `callback` via a `bmqa::StopStatus`, providing the status the
158+
/// operation. No method may be used after this method returns.
159+
///
160+
/// THREAD: The `callback` will *ALWAYS* be invoked from the EventHandler
161+
/// thread(s) (or if a SessionEventHandler was not specified, from
162+
/// the thread invoking `nextEvent`).
163+
virtual void stopAsync(const StopCallback& callback);
164+
122165
/// **DEPRECATED**
123166
///
124167
/// This method is only to be used if the session is in synchronous mode

src/groups/bmq/bmqa/bmqa_mocksession.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,13 @@ MockSession::Call::Call(Method method, bslma::Allocator* allocator)
562562
, d_openQueueCallback(bsl::allocator_arg, allocator)
563563
, d_configureQueueCallback(bsl::allocator_arg, allocator)
564564
, d_closeQueueCallback(bsl::allocator_arg, allocator)
565+
, d_startCallback(bsl::allocator_arg, allocator)
566+
, d_stopCallback(bsl::allocator_arg, allocator)
565567
, d_openQueueResult(allocator)
566568
, d_configureQueueResult(allocator)
567569
, d_closeQueueResult(allocator)
570+
, d_startResult(allocator)
571+
, d_stopResult(allocator)
568572
, d_emittedEvents(allocator)
569573
, d_returnEvent()
570574
, d_messageEvent()
@@ -590,9 +594,13 @@ MockSession::Call::Call(const Call& other, bslma::Allocator* allocator)
590594
, d_closeQueueCallback(bsl::allocator_arg,
591595
allocator,
592596
other.d_closeQueueCallback)
597+
, d_startCallback(bsl::allocator_arg, allocator, other.d_startCallback)
598+
, d_stopCallback(bsl::allocator_arg, allocator, other.d_stopCallback)
593599
, d_openQueueResult(other.d_openQueueResult)
594600
, d_configureQueueResult(other.d_configureQueueResult, allocator)
595601
, d_closeQueueResult(other.d_closeQueueResult, allocator)
602+
, d_startResult(other.d_startResult, allocator)
603+
, d_stopResult(other.d_stopResult, allocator)
596604
, d_emittedEvents(other.d_emittedEvents, allocator)
597605
, d_returnEvent(other.d_returnEvent)
598606
, d_messageEvent(other.d_messageEvent)
@@ -745,6 +753,56 @@ MockSession::Call::emitting(const CloseQueueStatus& closeQueueResult)
745753
return *this;
746754
}
747755

756+
MockSession::Call& MockSession::Call::emitting(const StartStatus& startResult)
757+
{
758+
// PRECONDITIONS
759+
BSLS_ASSERT_SAFE(d_method = e_START_ASYNC_CALLBACK);
760+
BSLS_ASSERT_SAFE(d_startCallback);
761+
762+
d_startResult = startResult;
763+
764+
const CallbackFn callbackFn = bdlf::BindUtil::bindS(d_allocator_p,
765+
d_startCallback,
766+
startResult);
767+
768+
// Start is a session-level operation with no associated queue, so
769+
// 'processIfQueueJob' will ignore this job (it only acts on queue events).
770+
Job job;
771+
job.d_callback = callbackFn;
772+
job.d_type = bmqt::SessionEventType::e_CONNECTED;
773+
job.d_status = startResult.result();
774+
775+
EventOrJob eventOrJob(job, d_allocator_p);
776+
d_emittedEvents.push_back(eventOrJob);
777+
778+
return *this;
779+
}
780+
781+
MockSession::Call& MockSession::Call::emitting(const StopStatus& stopResult)
782+
{
783+
// PRECONDITIONS
784+
BSLS_ASSERT_SAFE(d_method = e_STOP_ASYNC_CALLBACK);
785+
BSLS_ASSERT_SAFE(d_stopCallback);
786+
787+
d_stopResult = stopResult;
788+
789+
const CallbackFn callbackFn = bdlf::BindUtil::bindS(d_allocator_p,
790+
d_stopCallback,
791+
stopResult);
792+
793+
// Stop is a session-level operation with no associated queue, so
794+
// 'processIfQueueJob' will ignore this job (it only acts on queue events).
795+
Job job;
796+
job.d_callback = callbackFn;
797+
job.d_type = bmqt::SessionEventType::e_DISCONNECTED;
798+
job.d_status = stopResult.result();
799+
800+
EventOrJob eventOrJob(job, d_allocator_p);
801+
d_emittedEvents.push_back(eventOrJob);
802+
803+
return *this;
804+
}
805+
748806
const char* MockSession::Call::methodName() const
749807
{
750808
return MockSession::toAscii(d_method);
@@ -792,8 +850,13 @@ const char* MockSession::toAscii(const Method method)
792850
switch (method) {
793851
case e_START: return "start()";
794852
case e_START_ASYNC: return "startAsync()";
853+
case e_START_ASYNC_CALLBACK:
854+
return "int startAsync(const StartCallback& callback,"
855+
"const bsls::TimeInterval& timeout)";
795856
case e_STOP: return "stop()";
796857
case e_STOP_ASYNC: return "stopAsync()";
858+
case e_STOP_ASYNC_CALLBACK:
859+
return "void stopAsync(const StopCallback& callback)";
797860
case e_FINALIZE_STOP: return "finalizeStop()";
798861
case e_OPEN_QUEUE:
799862
return "int openQueue(QueueId *queueId,"
@@ -1227,6 +1290,21 @@ MockSession::expect_startAsync(const bsls::TimeInterval& timeout)
12271290
return call;
12281291
}
12291292

1293+
MockSession::Call&
1294+
MockSession::expect_startAsync(const StartCallback& callback,
1295+
const bsls::TimeInterval& timeout)
1296+
{
1297+
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
1298+
1299+
d_calls.emplace_back(e_START_ASYNC_CALLBACK);
1300+
Call& call = d_calls.back();
1301+
call.d_startCallback = callback;
1302+
call.d_timeout = timeout;
1303+
call.d_allocator_p = d_allocator_p;
1304+
1305+
return call;
1306+
}
1307+
12301308
MockSession::Call& MockSession::expect_stop()
12311309
{
12321310
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
@@ -1243,6 +1321,18 @@ MockSession::Call& MockSession::expect_stopAsync()
12431321
return d_calls.back();
12441322
}
12451323

1324+
MockSession::Call& MockSession::expect_stopAsync(const StopCallback& callback)
1325+
{
1326+
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
1327+
1328+
d_calls.emplace_back(e_STOP_ASYNC_CALLBACK);
1329+
Call& call = d_calls.back();
1330+
call.d_stopCallback = callback;
1331+
call.d_allocator_p = d_allocator_p;
1332+
1333+
return call;
1334+
}
1335+
12461336
MockSession::Call& MockSession::expect_finalizeStop()
12471337
{
12481338
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
@@ -1584,6 +1674,27 @@ int MockSession::startAsync(const bsls::TimeInterval& timeout)
15841674
return rc;
15851675
}
15861676

1677+
int MockSession::startAsync(BSLA_MAYBE_UNUSED const StartCallback& callback,
1678+
const bsls::TimeInterval& timeout)
1679+
{
1680+
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
1681+
1682+
BMQA_CHECK_CALL(e_START_ASYNC_CALLBACK, { return 0; });
1683+
BMQA_CHECK_ARG(e_START_ASYNC_CALLBACK,
1684+
"timeout",
1685+
call.d_timeout,
1686+
timeout,
1687+
call);
1688+
1689+
d_eventsAndJobs.insert(d_eventsAndJobs.end(),
1690+
call.d_emittedEvents.begin(),
1691+
call.d_emittedEvents.end());
1692+
1693+
const int rc = call.d_rc;
1694+
BMQA_ASSERT_AND_POP_FRONT();
1695+
return rc;
1696+
}
1697+
15871698
void MockSession::stop()
15881699
{
15891700
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
@@ -1628,6 +1739,28 @@ void MockSession::stopAsync()
16281739
BMQA_ASSERT_AND_POP_FRONT();
16291740
}
16301741

1742+
void MockSession::stopAsync(BSLA_MAYBE_UNUSED const StopCallback& callback)
1743+
{
1744+
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED
1745+
1746+
BMQA_CHECK_CALL(e_STOP_ASYNC_CALLBACK, {});
1747+
1748+
d_eventsAndJobs.insert(d_eventsAndJobs.end(),
1749+
call.d_emittedEvents.begin(),
1750+
call.d_emittedEvents.end());
1751+
1752+
// Reset all queue's state to 'closed' to mimic the real implementation
1753+
UriCorrIdToQueueMap& queueMap = uriCorrIdToQueues(d_twoKeyHashMapBuffer);
1754+
UriCorrIdToQueueMap::iterator qIt = queueMap.begin();
1755+
while (qIt != queueMap.end()) {
1756+
QueueImplSp& queueImpl = reinterpret_cast<QueueImplSp&>(qIt->value());
1757+
queueImpl->setState(bmqimp::QueueState::e_CLOSED);
1758+
++qIt;
1759+
}
1760+
1761+
BMQA_ASSERT_AND_POP_FRONT();
1762+
}
1763+
16311764
void MockSession::finalizeStop()
16321765
{
16331766
bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex); // LOCKED

0 commit comments

Comments
 (0)