Skip to content

Commit d5b4962

Browse files
author
jparisu
committed
Refs #15841: Return to monitor creation and add error handle
Signed-off-by: jparisu <[email protected]>
1 parent a07fbcf commit d5b4962

File tree

6 files changed

+148
-88
lines changed

6 files changed

+148
-88
lines changed

examples/cpp/HelloWorldExample/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <string>
2121

22+
#include <fastdds/dds/log/Log.hpp>
23+
2224
#include "arg_configuration.h"
2325
#include "HelloWorldPublisher.h"
2426
#include "HelloWorldSubscriber.h"

src/cpp/Monitor.hpp

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,24 @@
2222
#include <map>
2323
#include <string>
2424

25-
#include <fastdds/dds/domain/DomainParticipant.hpp>
26-
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
27-
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
28-
#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
29-
#include <fastdds/dds/subscriber/DataReader.hpp>
30-
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
31-
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
32-
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
33-
#include <fastdds/dds/subscriber/Subscriber.hpp>
34-
#include <fastdds/dds/topic/qos/TopicQos.hpp>
35-
#include <fastdds/dds/topic/Topic.hpp>
36-
3725
#include <fastdds_statistics_backend/listener/DomainListener.hpp>
3826
#include <fastdds_statistics_backend/listener/CallbackMask.hpp>
3927
#include <fastdds_statistics_backend/types/EntityId.hpp>
4028

4129
namespace eprosima {
30+
namespace fastdds {
31+
namespace dds {
32+
33+
class DomainParticipant;
34+
class DomainParticipantListener;
35+
class Subscriber;
36+
class Topic;
37+
class DataReader;
38+
class DataReaderListener;
39+
40+
} // namespace dds
41+
} // namespace fastdds
42+
4243
namespace statistics_backend {
4344
namespace details {
4445

@@ -49,50 +50,6 @@ namespace details {
4950
*/
5051
struct Monitor
5152
{
52-
/**
53-
* @brief Destroy the Monitor object
54-
*
55-
* Destroy every pointer that has been set.
56-
* This method works even if the monitor creation has failed
57-
*
58-
* @warning this may not be the best way to implement the destruction of subentities, as they are not created
59-
* under this class. But it is very convenience so it is reused during Monitor creation in case an error occurs
60-
* and also it is used to normally destroy the Monitor.
61-
*/
62-
~Monitor()
63-
{
64-
// These values are not always set, as could come from an error creating Monitor, or for test sake.
65-
if (participant)
66-
{
67-
if (subscriber)
68-
{
69-
for (auto& reader : readers)
70-
{
71-
subscriber->delete_datareader(reader.second);
72-
}
73-
74-
participant->delete_subscriber(subscriber);
75-
}
76-
77-
for (auto& topic : topics)
78-
{
79-
participant->delete_topic(topic.second);
80-
}
81-
82-
fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(participant);
83-
}
84-
85-
if (reader_listener)
86-
{
87-
delete reader_listener;
88-
}
89-
90-
if (participant_listener)
91-
{
92-
delete participant_listener;
93-
}
94-
}
95-
9653
//! The EntityId of the monitored domain
9754
EntityId id{};
9855

@@ -112,7 +69,6 @@ struct Monitor
11269
//! It will process the entity discoveries
11370
fastdds::dds::DomainParticipantListener* participant_listener = nullptr;
11471

115-
11672
//! The participant created to communicate with the statistics reporting publishers in this monitor
11773
fastdds::dds::Subscriber* subscriber = nullptr;
11874

src/cpp/StatisticsBackend.cpp

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,32 @@ EntityId create_and_register_monitor(
185185
details::StatisticsBackendData::get_instance()->lock();
186186

187187
// Create monitor instance.
188-
// NOTE: register in database at the end, in case any creation fails
189188
std::shared_ptr<details::Monitor> monitor = std::make_shared<details::Monitor>();
190189
std::shared_ptr<database::Domain> domain = std::make_shared<database::Domain>(domain_name);
191190

191+
try
192+
{
193+
domain->id = details::StatisticsBackendData::get_instance()->database_->insert(domain);
194+
}
195+
catch (const std::exception&)
196+
{
197+
details::StatisticsBackendData::get_instance()->unlock();
198+
throw;
199+
}
200+
// TODO: in case this function fails afterwards, the domain will be kept in the database without associated
201+
// Participant. There must exist a way in database to delete a domain, or to make a rollback.
202+
203+
monitor->id = domain->id;
192204
monitor->domain_listener = domain_listener;
193205
monitor->domain_callback_mask = callback_mask;
194206
monitor->data_mask = data_mask;
207+
details::StatisticsBackendData::get_instance()->monitors_by_entity_[domain->id] = monitor;
195208

209+
monitor->participant_listener = new subscriber::StatisticsParticipantListener(
210+
domain->id,
211+
details::StatisticsBackendData::get_instance()->database_.get(),
212+
details::StatisticsBackendData::get_instance()->entity_queue_,
213+
details::StatisticsBackendData::get_instance()->data_queue_);
196214
monitor->reader_listener = new subscriber::StatisticsReaderListener(
197215
details::StatisticsBackendData::get_instance()->data_queue_);
198216

@@ -207,6 +225,10 @@ EntityId create_and_register_monitor(
207225

208226
if (monitor->participant == nullptr)
209227
{
228+
// Remove those elements that have been set
229+
delete monitor->reader_listener;
230+
delete monitor->participant_listener;
231+
210232
details::StatisticsBackendData::get_instance()->unlock();
211233
throw Error("Error initializing monitor. Could not create participant");
212234
}
@@ -219,6 +241,11 @@ EntityId create_and_register_monitor(
219241

220242
if (monitor->subscriber == nullptr)
221243
{
244+
// Remove those elements that have been set
245+
DomainParticipantFactory::get_instance()->delete_participant(monitor->participant);
246+
delete monitor->reader_listener;
247+
delete monitor->participant_listener;
248+
222249
details::StatisticsBackendData::get_instance()->unlock();
223250
throw Error("Error initializing monitor. Could not create subscriber");
224251
}
@@ -230,6 +257,26 @@ EntityId create_and_register_monitor(
230257

231258
if (monitor->topics[topic] == nullptr)
232259
{
260+
// Remove those elements that have been set
261+
for (auto& it : monitor->readers)
262+
{
263+
if (nullptr != it.second)
264+
{
265+
monitor->subscriber->delete_datareader(it.second);
266+
}
267+
}
268+
for (auto& it : monitor->topics)
269+
{
270+
if (nullptr != it.second)
271+
{
272+
monitor->participant->delete_topic(it.second);
273+
}
274+
}
275+
monitor->participant->delete_subscriber(monitor->subscriber);
276+
DomainParticipantFactory::get_instance()->delete_participant(monitor->participant);
277+
delete monitor->reader_listener;
278+
delete monitor->participant_listener;
279+
233280
details::StatisticsBackendData::get_instance()->unlock();
234281
throw Error("Error initializing monitor. Could not create topic " + std::string(topic));
235282
}
@@ -243,33 +290,31 @@ EntityId create_and_register_monitor(
243290

244291
if (monitor->readers[topic] == nullptr)
245292
{
293+
// Remove those elements that have been set
294+
for (auto& it : monitor->readers)
295+
{
296+
if (nullptr != it.second)
297+
{
298+
monitor->subscriber->delete_datareader(it.second);
299+
}
300+
}
301+
for (auto& it : monitor->topics)
302+
{
303+
if (nullptr != it.second)
304+
{
305+
monitor->participant->delete_topic(it.second);
306+
}
307+
}
308+
monitor->participant->delete_subscriber(monitor->subscriber);
309+
DomainParticipantFactory::get_instance()->delete_participant(monitor->participant);
310+
delete monitor->reader_listener;
311+
delete monitor->participant_listener;
312+
246313
details::StatisticsBackendData::get_instance()->unlock();
247314
throw Error("Error initializing monitor. Could not create reader for topic " + std::string(topic));
248315
}
249316
}
250317

251-
// Insert domain entity in database
252-
try
253-
{
254-
domain->id = details::StatisticsBackendData::get_instance()->database_->insert(domain);
255-
}
256-
catch (const std::exception&)
257-
{
258-
details::StatisticsBackendData::get_instance()->unlock();
259-
throw;
260-
}
261-
262-
// Insert monitor as a new monitor entity.
263-
// NOTE: Monitor Id is only set after insert domain in database
264-
monitor->id = domain->id;
265-
details::StatisticsBackendData::get_instance()->monitors_by_entity_[domain->id] = monitor;
266-
267-
monitor->participant_listener = new subscriber::StatisticsParticipantListener(
268-
domain->id,
269-
details::StatisticsBackendData::get_instance()->database_.get(),
270-
details::StatisticsBackendData::get_instance()->entity_queue_,
271-
details::StatisticsBackendData::get_instance()->data_queue_);
272-
273318
details::StatisticsBackendData::get_instance()->unlock();
274319
return domain->id;
275320
}

src/cpp/StatisticsBackendData.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <fastdds/dds/domain/DomainParticipant.hpp>
2424
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
25+
#include <fastdds/dds/domain/qos/DomainParticipantFactoryQos.hpp>
2526
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
2627
#include <fastdds/dds/subscriber/DataReader.hpp>
2728
#include <fastdds/dds/subscriber/Subscriber.hpp>
@@ -51,7 +52,10 @@ StatisticsBackendData::StatisticsBackendData()
5152
, lock_(mutex_, std::defer_lock)
5253
, participant_factory_instance_(eprosima::fastdds::dds::DomainParticipantFactory::get_shared_instance())
5354
{
54-
// Do nothing
55+
// Set in DomainParticipantFactory that entities are created disabled
56+
eprosima::fastdds::dds::DomainParticipantFactoryQos qos;
57+
participant_factory_instance_->get_qos(qos);
58+
qos.entity_factory().autoenable_created_entities = false;
5559
}
5660

5761
StatisticsBackendData::~StatisticsBackendData()
@@ -363,7 +367,36 @@ void StatisticsBackendData::stop_monitor(
363367
monitors_by_entity_.erase(it);
364368

365369
// Delete everything created during monitor initialization
366-
monitor.reset();
370+
// These values are not always set, as could come from an error creating Monitor, or for test sake.
371+
if (monitor->participant)
372+
{
373+
if (monitor->subscriber)
374+
{
375+
for (auto& reader : monitor->readers)
376+
{
377+
monitor->subscriber->delete_datareader(reader.second);
378+
}
379+
380+
monitor->participant->delete_subscriber(monitor->subscriber);
381+
}
382+
383+
for (auto& topic : monitor->topics)
384+
{
385+
monitor->participant->delete_topic(topic.second);
386+
}
387+
388+
fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(monitor->participant);
389+
}
390+
391+
if (monitor->reader_listener)
392+
{
393+
delete monitor->reader_listener;
394+
}
395+
396+
if (monitor->participant_listener)
397+
{
398+
delete monitor->participant_listener;
399+
}
367400

368401
// The monitor is inactive
369402
// NOTE: for test sake, this is not always set

test/mock/dds/DomainParticipant/fastdds/dds/domain/DomainParticipant.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ class DomainParticipant
187187
const std::string& type_name
188188
));
189189

190+
MOCK_METHOD0(
191+
enable,
192+
ReturnCode_t
193+
());
194+
190195
DomainParticipantQos qos_;
191196
DomainId_t domain_id_;
192197
eprosima::fastrtps::rtps::GUID_t guid_;

test/mock/dds/DomainParticipantFactory/fastdds/dds/domain/DomainParticipantFactory.hpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <fastdds/dds/core/status/StatusMask.hpp>
2828
#include <fastdds/dds/domain/DomainParticipant.hpp>
29+
#include <fastdds/dds/domain/qos/DomainParticipantFactoryQos.hpp>
2930
#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
3031
#include <fastrtps/types/TypesBase.h>
3132

@@ -96,16 +97,34 @@ class DomainParticipantFactory
9697
const DomainParticipantQos& get_default_participant_qos()
9798
{
9899
get_default_participant_qos_count++;
99-
return qos;
100+
return participant_qos;
100101
}
101102

102-
DomainParticipantQos qos{};
103+
ReturnCode_t get_qos(DomainParticipantFactoryQos& qos) const
104+
{
105+
get_qos_count++;
106+
qos = factory_qos;
107+
return fastrtps::types::ReturnCode_t::RETCODE_OK;
108+
}
109+
110+
ReturnCode_t set_qos(
111+
const DomainParticipantFactoryQos& qos)
112+
{
113+
set_qos_count++;
114+
factory_qos = qos;
115+
return fastrtps::types::ReturnCode_t::RETCODE_OK;
116+
}
117+
118+
DomainParticipantFactoryQos factory_qos{};
119+
DomainParticipantQos participant_qos{};
103120
DomainParticipant* domain_participant = nullptr;
104121

105-
unsigned int load_profiles_count = 0;
106-
unsigned int create_participant_count = 0;
107-
unsigned int delete_participant_count = 0;
108-
unsigned int get_default_participant_qos_count = 0;
122+
mutable unsigned int load_profiles_count = 0;
123+
mutable unsigned int create_participant_count = 0;
124+
mutable unsigned int delete_participant_count = 0;
125+
mutable unsigned int get_default_participant_qos_count = 0;
126+
mutable unsigned int get_qos_count = 0;
127+
mutable unsigned int set_qos_count = 0;
109128

110129
};
111130

0 commit comments

Comments
 (0)