Skip to content
This repository was archived by the owner on Jul 8, 2022. It is now read-only.

Commit 464f5b1

Browse files
authored
Merge pull request #573 from mliszcz/fix-496-blind-event-clients-after-dev-restart-attempt-2
Fix #496 blind event clients after dev restart (attempt 2)
2 parents 51359b2 + 3eb67d6 commit 464f5b1

File tree

12 files changed

+152
-59
lines changed

12 files changed

+152
-59
lines changed

cpp_test_suite/new_tests/cxx_dserver_misc.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66
#undef SUITE_NAME
77
#define SUITE_NAME DServerMiscTestSuite
88

9+
struct EventCallback : public Tango::CallBack
10+
{
11+
EventCallback()
12+
: num_of_all_events(0)
13+
, num_of_error_events(0)
14+
{}
15+
16+
void push_event(Tango::EventData* event)
17+
{
18+
num_of_all_events++;
19+
if (event->err)
20+
{
21+
num_of_error_events++;
22+
}
23+
}
24+
25+
int num_of_all_events;
26+
int num_of_error_events;
27+
};
28+
929
class DServerMiscTestSuite: public CxxTest::TestSuite
1030
{
1131
protected:
@@ -203,6 +223,38 @@ cout << "str = " << str << endl;
203223
TS_ASSERT(dserver->info().server_id == full_ds_name);
204224
TS_ASSERT(dserver->info().server_version == server_version);
205225
}
226+
227+
/* Tests that subscriber can receive events immediately after
228+
* a device restart without a need to wait for re-subscription.
229+
*/
230+
void test_event_subscription_recovery_after_device_restart()
231+
{
232+
EventCallback callback{};
233+
234+
std::string attribute_name = "event_change_tst";
235+
236+
TS_ASSERT_THROWS_NOTHING(device1->subscribe_event(
237+
attribute_name,
238+
Tango::USER_EVENT,
239+
&callback));
240+
241+
TS_ASSERT_THROWS_NOTHING(device1->command_inout("IOPushEvent"));
242+
Tango_sleep(2);
243+
TS_ASSERT_EQUALS(2, callback.num_of_all_events);
244+
TS_ASSERT_EQUALS(0, callback.num_of_error_events);
245+
246+
{
247+
Tango::DeviceData input{};
248+
input << device1_name;
249+
TS_ASSERT_THROWS_NOTHING(dserver->command_inout("DevRestart", input));
250+
}
251+
252+
TS_ASSERT_THROWS_NOTHING(device1->command_inout("IOPushEvent"));
253+
Tango_sleep(2);
254+
TS_ASSERT_EQUALS(3, callback.num_of_all_events);
255+
TS_ASSERT_EQUALS(0, callback.num_of_error_events);
256+
}
257+
206258
};
207259
#undef cout
208260
#endif // DServerMiscTestSuite_h

cppapi/server/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ set(HEADERS attrdesc.h
128128
w_pipe.tpp
129129
subdev_diag.h
130130
encoded_attribute.h
131-
encoded_format.h)
131+
encoded_format.h
132+
event_subscription_state.h)
132133

133134
add_subdirectory(idl)
134135
add_subdirectory(jpeg)

cppapi/server/attribute.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5912,21 +5912,18 @@ bool Attribute::data_ready_event_subscribed()
59125912
//
59135913
//--------------------------------------------------------------------------------------------------------------------
59145914

5915-
void Attribute::set_client_lib(int _l,std::string &ev_name)
5915+
void Attribute::set_client_lib(int client_lib_version, EventType event_type)
59165916
{
5917-
cout4 << "Attribute::set_client_lib(" << _l << "," << ev_name << ")" << std::endl;
5918-
int i;
5919-
for (i = 0; i < numEventType; i++)
5920-
{
5921-
if (ev_name == EventName[i])
5922-
{
5923-
break;
5924-
}
5925-
}
5917+
cout4 << "Attribute::set_client_lib("
5918+
<< client_lib_version << ","
5919+
<< EventName[event_type] << ")" << std::endl;
59265920

5927-
if (count(client_lib[i].begin(), client_lib[i].end(), _l) == 0)
5921+
if (0 == count(
5922+
client_lib[event_type].begin(),
5923+
client_lib[event_type].end(),
5924+
client_lib_version))
59285925
{
5929-
client_lib[i].push_back(_l);
5926+
client_lib[event_type].push_back(client_lib_version);
59305927
}
59315928
}
59325929

cppapi/server/attribute.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,9 +2308,9 @@ class Attribute
23082308
bool is_mem_exception() {return att_mem_exception;}
23092309
virtual bool is_fwd_att() {return false;}
23102310

2311-
void set_client_lib(int,std::string &);
2311+
void set_client_lib(int, EventType);
23122312
std::vector<int> &get_client_lib(EventType _et) {return client_lib[_et];}
2313-
void remove_client_lib(int,const std::string &);
2313+
void remove_client_lib(int, const std::string &);
23142314

23152315
void add_config_5_specific(AttributeConfig_5 &);
23162316
void add_startup_exception(std::string,const DevFailed &);

cppapi/server/device.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6106,17 +6106,17 @@ void DeviceImpl::remove_local_command(const std::string &cmd_name)
61066106
//
61076107
//------------------------------------------------------------------------------------------------------------------
61086108

6109-
void DeviceImpl::get_event_param(std::vector<EventPar> &eve)
6109+
void DeviceImpl::get_event_param(EventSubscriptionStates& eve)
61106110
{
61116111
ZmqEventSupplier *event_supplier_zmq = Util::instance()->get_zmq_event_supplier();
61126112

61136113
if (event_supplier_zmq->any_dev_intr_client(this) == true)
61146114
{
6115-
EventPar ep;
6115+
EventSubscriptionState ep;
61166116

61176117
ep.notifd = false;
61186118
ep.zmq = true;
6119-
ep.attr_id = -1;
6119+
ep.attribute_name = "";
61206120
ep.quality = false;
61216121
ep.data_ready = false;
61226122
ep.dev_intr_change = true;
@@ -6139,11 +6139,11 @@ void DeviceImpl::get_event_param(std::vector<EventPar> &eve)
61396139
//
61406140
//------------------------------------------------------------------------------------------------------------------
61416141

6142-
void DeviceImpl::set_event_param(std::vector<EventPar> &eve)
6142+
void DeviceImpl::set_event_param(const EventSubscriptionStates& eve)
61436143
{
61446144
for (size_t loop = 0; loop < eve.size(); loop++)
61456145
{
6146-
if (eve[loop].attr_id == -1)
6146+
if (eve[loop].attribute_name.empty())
61476147
{
61486148
if (eve[loop].dev_intr_change == true)
61496149
{

cppapi/server/device.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <deviceclass.h>
4646
#include <devintr.h>
4747
#include <dintrthread.h>
48+
#include "event_subscription_state.h"
4849

4950
namespace Tango
5051
{
@@ -3423,8 +3424,8 @@ class DeviceImpl : public virtual POA_Tango::Device
34233424
void disable_intr_change_ev() {intr_change_ev = false;}
34243425
bool is_intr_change_ev_enable() {return intr_change_ev;}
34253426

3426-
void get_event_param(std::vector<EventPar> &);
3427-
void set_event_param(std::vector<EventPar> &);
3427+
void get_event_param(EventSubscriptionStates&);
3428+
void set_event_param(const EventSubscriptionStates&);
34283429

34293430
void set_client_lib(int _l) {if (count(client_lib.begin(),client_lib.end(),_l)==0)client_lib.push_back(_l);}
34303431

cppapi/server/dserver.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ void DServer::restart(std::string &d_name)
882882

883883
std::vector<PollObj *> &p_obj = dev_to_del->get_poll_obj_list();
884884
std::vector<Pol> dev_pol;
885-
std::vector<EventPar> eve;
885+
EventSubscriptionStates eve;
886886

887887
for (i = 0;i < p_obj.size();i++)
888888
{
@@ -1193,7 +1193,7 @@ void ServRestartThread::run(void *ptr)
11931193
// Memorize event parameters and devices interface
11941194
//
11951195

1196-
std::map<std::string,std::vector<EventPar> > map_events;
1196+
ServerEventSubscriptionState map_events;
11971197
std::map<std::string,DevIntr> map_dev_inter;
11981198

11991199
dev->mem_event_par(map_events);
@@ -1977,14 +1977,14 @@ void DServer::mcast_event_for_att(std::string &dev_name,std::string &att_name,st
19771977
//
19781978
//------------------------------------------------------------------------------------------------------------------
19791979

1980-
void DServer::mem_event_par(std::map<std::string,std::vector<EventPar> > &_map)
1980+
void DServer::mem_event_par(ServerEventSubscriptionState& _map)
19811981
{
19821982
for (size_t i = 0;i < class_list.size();i++)
19831983
{
19841984
std::vector<DeviceImpl *> &dev_list = class_list[i]->get_device_list();
19851985
for (size_t j = 0;j < dev_list.size();j++)
19861986
{
1987-
std::vector<EventPar> eve;
1987+
EventSubscriptionStates eve;
19881988
dev_list[j]->get_device_attr()->get_event_param(eve);
19891989
dev_list[j]->get_event_param(eve);
19901990

@@ -2010,16 +2010,16 @@ void DServer::mem_event_par(std::map<std::string,std::vector<EventPar> > &_map)
20102010
//
20112011
//------------------------------------------------------------------------------------------------------------------
20122012

2013-
void DServer::apply_event_par(std::map<std::string,std::vector<EventPar> > &_map)
2013+
void DServer::apply_event_par(const ServerEventSubscriptionState& _map)
20142014
{
20152015
for (size_t i = 0;i < class_list.size();i++)
20162016
{
20172017
std::vector<DeviceImpl *> &dev_list = class_list[i]->get_device_list();
20182018
for (size_t j = 0;j < dev_list.size();j++)
20192019
{
20202020
std::string &dev_name = dev_list[j]->get_name();
2021-
std::map<std::string,std::vector<EventPar> >::iterator ite;
2022-
ite = _map.find(dev_name);
2021+
2022+
const auto ite = _map.find(dev_name);
20232023

20242024
if (ite != _map.end())
20252025
{

cppapi/server/dserver.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define _DSERVER_H
3939

4040
#include <tango.h>
41+
#include "event_subscription_state.h"
4142

4243
namespace Tango
4344
{
@@ -128,8 +129,8 @@ public :
128129
void _create_cpp_class(const char *c1,const char *c2) {this->create_cpp_class(c1,c2);}
129130

130131
void mcast_event_for_att(std::string &,std::string &,std::vector<std::string> &);
131-
void mem_event_par(std::map<std::string, std::vector<EventPar> > &);
132-
void apply_event_par(std::map<std::string,std::vector<EventPar> > &);
132+
void mem_event_par(ServerEventSubscriptionState&);
133+
void apply_event_par(const ServerEventSubscriptionState&);
133134

134135
void mem_devices_interface(std::map<std::string,DevIntr> &);
135136
void changed_devices_interface(std::map<std::string,DevIntr> &);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef _EVENT_SUBSCRIPTION_STATE_H
2+
#define _EVENT_SUBSCRIPTION_STATE_H
3+
4+
#include <map>
5+
#include <vector>
6+
#include <string>
7+
8+
namespace Tango
9+
{
10+
11+
using EventClientLibVersion = int;
12+
using EventClientLibVersions = std::vector<EventClientLibVersion>;
13+
14+
struct EventSubscriptionState
15+
{
16+
std::string attribute_name;
17+
18+
EventClientLibVersions change;
19+
EventClientLibVersions archive;
20+
EventClientLibVersions periodic;
21+
EventClientLibVersions user;
22+
EventClientLibVersions att_conf;
23+
24+
bool quality;
25+
bool data_ready;
26+
bool dev_intr_change;
27+
28+
bool notifd;
29+
bool zmq;
30+
};
31+
32+
using EventSubscriptionStates = std::vector<EventSubscriptionState>;
33+
using ServerEventSubscriptionState = std::map<std::string, EventSubscriptionStates>;
34+
35+
}
36+
37+
#endif

cppapi/server/eventcmds.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,13 @@ void DServer::event_subscription(std::string &dev_name,std::string &obj_name,std
581581
//
582582

583583
if (client_lib != 0)
584-
{
585-
omni_mutex_lock oml(EventSupplier::get_event_mutex());
586-
attribute.set_client_lib(client_lib,event);
587-
}
584+
{
585+
EventType event_type = CHANGE_EVENT;
586+
tg->event_name_2_event_type(event, event_type);
587+
588+
omni_mutex_lock oml(EventSupplier::get_event_mutex());
589+
attribute.set_client_lib(client_lib, event_type);
590+
}
588591
}
589592
else if (event == EventName[PIPE_EVENT])
590593
{

0 commit comments

Comments
 (0)