Merge lp:~marcustomlinson/unity-scopes-api/scope_state_callback into lp:unity-scopes-api/devel
- scope_state_callback
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Pete Woods |
Approved revision: | 373 |
Merged at revision: | 366 |
Proposed branch: | lp:~marcustomlinson/unity-scopes-api/scope_state_callback |
Merge into: | lp:unity-scopes-api/devel |
Diff against target: |
993 lines (+334/-122) 25 files modified
debian/changelog (+7/-12) debian/control (+1/-0) debian/libunity-scopes1.symbols (+3/-2) include/unity/scopes/Registry.h (+21/-2) include/unity/scopes/internal/MWRegistry.h (+5/-2) include/unity/scopes/internal/MWSubscriber.h (+4/-3) include/unity/scopes/internal/RegistryImpl.h (+4/-1) include/unity/scopes/internal/RegistryObject.h (+4/-3) include/unity/scopes/internal/RegistryObjectBase.h (+1/-0) include/unity/scopes/internal/smartscopes/SSRegistryObject.h (+1/-0) include/unity/scopes/internal/zmq_middleware/RegistryI.h (+4/-0) include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h (+1/-0) include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h (+2/-7) include/unity/scopes/testing/MockRegistry.h (+9/-1) src/scopes/internal/MWRegistry.cpp (+15/-16) src/scopes/internal/MWSubscriber.cpp (+5/-0) src/scopes/internal/RegistryImpl.cpp (+13/-3) src/scopes/internal/RegistryObject.cpp (+53/-27) src/scopes/internal/smartscopes/SSRegistryObject.cpp (+5/-0) src/scopes/internal/zmq_middleware/RegistryI.cpp (+24/-1) src/scopes/internal/zmq_middleware/ZmqRegistry.cpp (+34/-0) src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp (+4/-16) src/scopes/internal/zmq_middleware/capnproto/Registry.capnp (+14/-0) test/gtest/scopes/Registry/Registry_test.cpp (+96/-22) test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp (+4/-4) |
To merge this branch: | bzr merge lp:~marcustomlinson/unity-scopes-api/scope_state_callback |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pete Woods (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+221247@code.launchpad.net |
Commit message
Introduced is_scope_running() and set_scope_
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:372
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Pete Woods (pete-woods) : | # |
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-05-29 14:08:41 +0000 |
3 | +++ debian/changelog 2014-06-03 08:58:50 +0000 |
4 | @@ -1,19 +1,14 @@ |
5 | -unity-scopes-api (0.4.8+14.10.20140519-0ubuntu1) UNRELEASED; urgency=medium |
6 | +unity-scopes-api (0.4.8-0ubuntu1) UNRELEASED; urgency=medium |
7 | + |
8 | + [ Pawel Stolowski ] |
9 | + * Changes to departments API. |
10 | |
11 | [ Marcus Tomlinson ] |
12 | * Introduced Dir/ScopesWatcher classes to watch for updates to the scope install directories. |
13 | - * Updated scoperegistry to inform the registry object when scopes are (un)installed. |
14 | * Updated all relevant registry classes to propagate an update pub/sub message via middleware. |
15 | - * Added set_update_callback() to Registry (callback executed when the scopes list changes). |
16 | - |
17 | - -- Marcus Tomlinson <marcustomlinson@ubuntu> Thu, 22 May 2014 06:47:28 +0200 |
18 | - |
19 | -unity-scopes-api (0.4.8-0ubuntu1) UNRELEASED; urgency=medium |
20 | - |
21 | - [ Pawel Stolowski ] |
22 | - * Changes to departments API. |
23 | - |
24 | - -- Pawel Stolowski <pawel.stolowski@ubuntu.com> Tue, 20 May 2014 16:40:56 +0200 |
25 | + * Added is_scope_running(), set_scope_state_callback() and set_update_callback() to Registry. |
26 | + |
27 | + -- Marcus Tomlinson <marcustomlinson@ubuntu> Wed, 28 May 2014 17:08:45 +0200 |
28 | |
29 | unity-scopes-api (0.4.7+14.10.20140522-0ubuntu1) utopic; urgency=low |
30 | |
31 | |
32 | === modified file 'debian/control' |
33 | --- debian/control 2014-05-22 17:52:29 +0000 |
34 | +++ debian/control 2014-06-03 08:58:50 +0000 |
35 | @@ -49,6 +49,7 @@ |
36 | Multi-Arch: same |
37 | Pre-Depends: ${misc:Pre-Depends}, |
38 | Depends: libunity-scopes1 (= ${binary:Version}), |
39 | + libproperties-cpp-dev, |
40 | libunity-api-dev, |
41 | ${misc:Depends}, |
42 | Description: Header files for Unity scopes API |
43 | |
44 | === modified file 'debian/libunity-scopes1.symbols' |
45 | --- debian/libunity-scopes1.symbols 2014-05-30 13:21:46 +0000 |
46 | +++ debian/libunity-scopes1.symbols 2014-06-03 08:58:50 +0000 |
47 | @@ -418,6 +418,7 @@ |
48 | (c++)"unity::scopes::internal::smartscopes::SSScopeObject::SSScopeObject(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<unity::scopes::internal::MiddlewareBase>, std::shared_ptr<unity::scopes::internal::smartscopes::SSRegistryObject>)@Base" 0.4.0+14.04.20140312.1 |
49 | (c++)"unity::scopes::internal::smartscopes::SSScopeObject::~SSScopeObject()@Base" 0.4.0+14.04.20140312.1 |
50 | (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::refresh_thread()@Base" 0.4.0+14.04.20140312.1 |
51 | + (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::is_scope_running(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme |
52 | (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::get_remote_scopes()@Base" 0.4.0+14.04.20140312.1 |
53 | (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::add(unity::scopes::internal::smartscopes::RemoteScope const&, unity::scopes::ScopeMetadata const&, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unity::scopes::ScopeMetadata, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unity::scopes::ScopeMetadata> > >&, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)@Base" 0.4.0+14.04.20140324 |
54 | (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::locate(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1 |
55 | @@ -438,9 +439,9 @@ |
56 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::exec(core::posix::ChildProcess::DeathObserver&, std::shared_ptr<unity::scopes::internal::Executor>)@Base" 0.4.3+14.10.20140428 |
57 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill(std::unique_lock<std::mutex>&)@Base" 0.4.2+14.04.20140404.2 |
58 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill()@Base" 0.4.2+14.04.20140404.2 |
59 | - (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData)@Base" 0.4.2+14.04.20140404.2 |
60 | + (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData, std::shared_ptr<unity::scopes::internal::MWPublisher>)@Base" 0replaceme |
61 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2 |
62 | - (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData)@Base" 0.4.2+14.04.20140404.2 |
63 | + (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData, std::shared_ptr<unity::scopes::internal::MWPublisher>)@Base" 0replaceme |
64 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2 |
65 | (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::~ScopeProcess()@Base" 0.4.2+14.04.20140404.2 |
66 | (c++)"unity::scopes::internal::RegistryObject::ScopeExecData::~ScopeExecData()@Base" 0.4.2+14.04.20140404.2 |
67 | |
68 | === modified file 'include/unity/scopes/Registry.h' |
69 | --- include/unity/scopes/Registry.h 2014-05-27 07:08:33 +0000 |
70 | +++ include/unity/scopes/Registry.h 2014-06-03 08:58:50 +0000 |
71 | @@ -19,6 +19,7 @@ |
72 | #ifndef UNITY_SCOPES_REGISTRY_H |
73 | #define UNITY_SCOPES_REGISTRY_H |
74 | |
75 | +#include <core/signal.h> |
76 | #include <unity/scopes/Object.h> |
77 | #include <unity/scopes/RegistryProxyFwd.h> |
78 | #include <unity/scopes/ScopeMetadata.h> |
79 | @@ -56,8 +57,9 @@ |
80 | |
81 | /** |
82 | \brief Returns the metadata for the scope with the given ID. |
83 | + \param scope_id The ID of the scope from which we wish to retrieve metadata. |
84 | \return The metadata for the scope. |
85 | - \throws NotFoundException if no scope with the given name exists. |
86 | + \throws NotFoundException if no scope with the given ID exists. |
87 | */ |
88 | virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0; |
89 | |
90 | @@ -75,13 +77,30 @@ |
91 | virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) = 0; |
92 | |
93 | /** |
94 | + \brief Returns whether a scope is currently running or not. |
95 | + \param scope_id The ID of the scope from which we wish to retrieve state. |
96 | + \return True if the scope is running, and False if it is not running. |
97 | + \throws NotFoundException if no scope with the given ID exists. |
98 | + */ |
99 | + virtual bool is_scope_running(std::string const& scope_id) = 0; |
100 | + |
101 | + /** |
102 | + \brief Assigns a callback method to be executed when a scope's running state (started / stopped) changes. |
103 | + \param scope_id The ID of the scope from which we wish to retrieve state changes. |
104 | + \param callback The function object that is invoked when a scope changes running state. |
105 | + \throws MiddlewareException if the registry subscriber failed to initialize. |
106 | + */ |
107 | + virtual core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool is_running)> callback) = 0; |
108 | + |
109 | + /** |
110 | \brief Assigns a callback method to be executed when the registry's scope list changes. |
111 | |
112 | Note: Upon receiving this callback, you should retrieve the updated scopes list via the list() method if |
113 | you wish to retain synchronisation between client and server. |
114 | \param callback The function object that is invoked when an update occurs. |
115 | + \throws MiddlewareException if the registry subscriber failed to initialize. |
116 | */ |
117 | - virtual void set_list_update_callback(std::function<void()> callback) = 0; |
118 | + virtual core::ScopedConnection set_list_update_callback(std::function<void()> callback) = 0; |
119 | |
120 | protected: |
121 | /// @cond |
122 | |
123 | === modified file 'include/unity/scopes/internal/MWRegistry.h' |
124 | --- include/unity/scopes/internal/MWRegistry.h 2014-05-27 07:08:33 +0000 |
125 | +++ include/unity/scopes/internal/MWRegistry.h 2014-06-03 08:58:50 +0000 |
126 | @@ -40,18 +40,21 @@ |
127 | virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0; |
128 | virtual MetadataMap list() = 0; |
129 | virtual ObjectProxy locate(std::string const& identity) = 0; |
130 | + virtual bool is_scope_running(std::string const& scope_id) = 0; |
131 | |
132 | virtual ~MWRegistry(); |
133 | |
134 | // Local operations |
135 | - void set_list_update_callback(std::function<void()> callback); |
136 | + core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback); |
137 | + core::ScopedConnection set_list_update_callback(std::function<void()> callback); |
138 | |
139 | protected: |
140 | MWRegistry(MiddlewareBase* mw_base); |
141 | |
142 | private: |
143 | MiddlewareBase* mw_base_; |
144 | - MWSubscriber::UPtr subscriber_; |
145 | + MWSubscriber::UPtr list_update_subscriber_; |
146 | + std::map<std::string, MWSubscriber::UPtr> scope_state_subscribers_; |
147 | }; |
148 | |
149 | } // namespace internal |
150 | |
151 | === modified file 'include/unity/scopes/internal/MWSubscriber.h' |
152 | --- include/unity/scopes/internal/MWSubscriber.h 2014-05-19 05:15:06 +0000 |
153 | +++ include/unity/scopes/internal/MWSubscriber.h 2014-06-03 08:58:50 +0000 |
154 | @@ -19,6 +19,7 @@ |
155 | #ifndef UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H |
156 | #define UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H |
157 | |
158 | +#include <core/signal.h> |
159 | #include <unity/util/DefinesPtrs.h> |
160 | #include <unity/util/NonCopyable.h> |
161 | |
162 | @@ -31,8 +32,6 @@ |
163 | namespace internal |
164 | { |
165 | |
166 | -typedef std::function<void(std::string const& message)> SubscriberCallback; |
167 | - |
168 | class MWSubscriber |
169 | { |
170 | public: |
171 | @@ -42,10 +41,12 @@ |
172 | virtual ~MWSubscriber(); |
173 | |
174 | virtual std::string endpoint() const = 0; |
175 | - virtual void set_message_callback(SubscriberCallback callback) = 0; |
176 | + core::Signal<std::string const&> const& message_received() const; |
177 | |
178 | protected: |
179 | MWSubscriber(); |
180 | + |
181 | + core::Signal<std::string const&> message_received_; |
182 | }; |
183 | |
184 | } // namespace internal |
185 | |
186 | === modified file 'include/unity/scopes/internal/RegistryImpl.h' |
187 | --- include/unity/scopes/internal/RegistryImpl.h 2014-05-27 07:08:33 +0000 |
188 | +++ include/unity/scopes/internal/RegistryImpl.h 2014-06-03 08:58:50 +0000 |
189 | @@ -43,7 +43,10 @@ |
190 | virtual ScopeMetadata get_metadata(std::string const& scope_id) override; |
191 | virtual MetadataMap list() override; |
192 | virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) override; |
193 | - virtual void set_list_update_callback(std::function<void()> callback) override; |
194 | + virtual bool is_scope_running(std::string const& scope_id) override; |
195 | + |
196 | + virtual core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback) override; |
197 | + virtual core::ScopedConnection set_list_update_callback(std::function<void()> callback) override; |
198 | |
199 | // Remote operation. Not part of public API, hence not override. |
200 | ObjectProxy locate(std::string const& identity); |
201 | |
202 | === modified file 'include/unity/scopes/internal/RegistryObject.h' |
203 | --- include/unity/scopes/internal/RegistryObject.h 2014-05-27 09:54:38 +0000 |
204 | +++ include/unity/scopes/internal/RegistryObject.h 2014-06-03 08:58:50 +0000 |
205 | @@ -65,6 +65,7 @@ |
206 | virtual ScopeMetadata get_metadata(std::string const& scope_id) const override; |
207 | virtual MetadataMap list() const override; |
208 | virtual ObjectProxy locate(std::string const& identity) override; |
209 | + virtual bool is_scope_running(std::string const& scope_id) override; |
210 | |
211 | // Local methods |
212 | bool add_local_scope(std::string const& scope_id, ScopeMetadata const& scope, |
213 | @@ -72,7 +73,6 @@ |
214 | bool remove_local_scope(std::string const& scope_id); |
215 | void set_remote_registry(MWRegistryProxy const& remote_registry); |
216 | |
217 | - bool is_scope_running(std::string const& scope_id); |
218 | StateReceiverObject::SPtr state_receiver(); |
219 | |
220 | private: |
221 | @@ -87,7 +87,7 @@ |
222 | Stopped, Starting, Running, Stopping |
223 | }; |
224 | |
225 | - ScopeProcess(ScopeExecData exec_data); |
226 | + ScopeProcess(ScopeExecData exec_data, MWPublisher::SPtr publisher); |
227 | ScopeProcess(ScopeProcess const& other); |
228 | ~ScopeProcess(); |
229 | |
230 | @@ -115,6 +115,7 @@ |
231 | mutable std::mutex process_mutex_; |
232 | mutable std::condition_variable state_change_cond_; |
233 | core::posix::ChildProcess process_ = core::posix::ChildProcess::invalid(); |
234 | + MWPublisher::SPtr reg_publisher_; |
235 | }; |
236 | |
237 | private: |
238 | @@ -132,7 +133,7 @@ |
239 | MWRegistryProxy remote_registry_; |
240 | mutable std::mutex mutex_; |
241 | |
242 | - MWPublisher::UPtr publisher_; |
243 | + MWPublisher::SPtr publisher_; |
244 | }; |
245 | |
246 | } // namespace internal |
247 | |
248 | === modified file 'include/unity/scopes/internal/RegistryObjectBase.h' |
249 | --- include/unity/scopes/internal/RegistryObjectBase.h 2014-04-03 12:57:25 +0000 |
250 | +++ include/unity/scopes/internal/RegistryObjectBase.h 2014-06-03 08:58:50 +0000 |
251 | @@ -39,6 +39,7 @@ |
252 | virtual ScopeMetadata get_metadata(std::string const& scope_id) const = 0; |
253 | virtual MetadataMap list() const = 0; |
254 | virtual ObjectProxy locate(std::string const& identity) = 0; |
255 | + virtual bool is_scope_running(std::string const& scope_id) = 0; |
256 | }; |
257 | |
258 | } // namespace internal |
259 | |
260 | === modified file 'include/unity/scopes/internal/smartscopes/SSRegistryObject.h' |
261 | --- include/unity/scopes/internal/smartscopes/SSRegistryObject.h 2014-05-09 05:26:39 +0000 |
262 | +++ include/unity/scopes/internal/smartscopes/SSRegistryObject.h 2014-06-03 08:58:50 +0000 |
263 | @@ -54,6 +54,7 @@ |
264 | MetadataMap list() const override; |
265 | |
266 | ObjectProxy locate(std::string const& identity) override; |
267 | + bool is_scope_running(std::string const& scope_id) override; |
268 | |
269 | bool has_scope(std::string const& scope_id) const; |
270 | std::string get_base_url(std::string const& scope_id) const; |
271 | |
272 | === modified file 'include/unity/scopes/internal/zmq_middleware/RegistryI.h' |
273 | --- include/unity/scopes/internal/zmq_middleware/RegistryI.h 2014-04-03 12:57:25 +0000 |
274 | +++ include/unity/scopes/internal/zmq_middleware/RegistryI.h 2014-06-03 08:58:50 +0000 |
275 | @@ -59,6 +59,10 @@ |
276 | virtual void locate_(Current const& current, |
277 | capnp::AnyPointer::Reader& in_params, |
278 | capnproto::Response::Builder& r); |
279 | + |
280 | + virtual void is_scope_running_(Current const& current, |
281 | + capnp::AnyPointer::Reader& in_params, |
282 | + capnproto::Response::Builder& r); |
283 | }; |
284 | |
285 | } // namespace zmq_middleware |
286 | |
287 | === modified file 'include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h' |
288 | --- include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-04-03 12:57:25 +0000 |
289 | +++ include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-06-03 08:58:50 +0000 |
290 | @@ -52,6 +52,7 @@ |
291 | virtual ScopeMetadata get_metadata(std::string const& scope_id) override; |
292 | virtual MetadataMap list() override; |
293 | virtual ObjectProxy locate(std::string const& identity) override; |
294 | + virtual bool is_scope_running(std::string const& scope_id) override; |
295 | }; |
296 | |
297 | } // namespace zmq_middleware |
298 | |
299 | === modified file 'include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h' |
300 | --- include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 2014-05-21 10:45:51 +0000 |
301 | +++ include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 2014-06-03 08:58:50 +0000 |
302 | @@ -19,13 +19,11 @@ |
303 | #ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H |
304 | #define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H |
305 | |
306 | +#include <condition_variable> |
307 | +#include <thread> |
308 | #include <unity/scopes/internal/MWSubscriber.h> |
309 | - |
310 | #include <zmqpp/context.hpp> |
311 | |
312 | -#include <condition_variable> |
313 | -#include <thread> |
314 | - |
315 | namespace unity |
316 | { |
317 | |
318 | @@ -48,7 +46,6 @@ |
319 | virtual ~ZmqSubscriber(); |
320 | |
321 | std::string endpoint() const override; |
322 | - void set_message_callback(SubscriberCallback callback) override; |
323 | |
324 | private: |
325 | enum ThreadState |
326 | @@ -70,8 +67,6 @@ |
327 | ThreadState thread_state_; |
328 | std::exception_ptr thread_exception_; |
329 | |
330 | - SubscriberCallback callback_; |
331 | - |
332 | void subscriber_thread(); |
333 | }; |
334 | |
335 | |
336 | === modified file 'include/unity/scopes/testing/MockRegistry.h' |
337 | --- include/unity/scopes/testing/MockRegistry.h 2014-05-27 07:08:33 +0000 |
338 | +++ include/unity/scopes/testing/MockRegistry.h 2014-06-03 08:58:50 +0000 |
339 | @@ -43,7 +43,15 @@ |
340 | MOCK_METHOD1(get_metadata, ScopeMetadata(std::string const&)); |
341 | MOCK_METHOD0(list, MetadataMap()); |
342 | MOCK_METHOD1(list_if, MetadataMap(std::function<bool(ScopeMetadata const&)>)); |
343 | - MOCK_METHOD1(set_list_update_callback, void(std::function<void()>)); |
344 | + MOCK_METHOD1(is_scope_running, bool(std::string const&)); |
345 | + core::ScopedConnection set_scope_state_callback(std::string const&, std::function<void(bool is_running)>) override |
346 | + { |
347 | + return core::Signal<>().connect([]{}); |
348 | + } |
349 | + core::ScopedConnection set_list_update_callback(std::function<void()>) override |
350 | + { |
351 | + return core::Signal<>().connect([]{}); |
352 | + } |
353 | }; |
354 | |
355 | /// @endcond |
356 | |
357 | === modified file 'src/scopes/internal/MWRegistry.cpp' |
358 | --- src/scopes/internal/MWRegistry.cpp 2014-05-27 07:08:33 +0000 |
359 | +++ src/scopes/internal/MWRegistry.cpp 2014-06-03 08:58:50 +0000 |
360 | @@ -41,24 +41,23 @@ |
361 | { |
362 | } |
363 | |
364 | -void MWRegistry::set_list_update_callback(std::function<void()> callback) |
365 | -{ |
366 | - if (!subscriber_) |
367 | +core::ScopedConnection MWRegistry::set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback) |
368 | +{ |
369 | + if (scope_state_subscribers_.find(scope_id) == scope_state_subscribers_.end()) |
370 | + { |
371 | + scope_state_subscribers_[scope_id] = mw_base_->create_subscriber(mw_base_->runtime()->registry_identity(), scope_id); |
372 | + } |
373 | + return scope_state_subscribers_.at(scope_id)->message_received().connect([callback](string const& state){ callback(state == "started"); }); |
374 | +} |
375 | + |
376 | +core::ScopedConnection MWRegistry::set_list_update_callback(std::function<void()> callback) |
377 | +{ |
378 | + if (!list_update_subscriber_) |
379 | { |
380 | // Use lazy initialization here to only subscribe to the publisher if a callback is set |
381 | - try |
382 | - { |
383 | - subscriber_ = mw_base_->create_subscriber(mw_base_->runtime()->registry_identity()); |
384 | - } |
385 | - catch (std::exception const& e) |
386 | - { |
387 | - cerr << "MWRegistry::set_list_update_callback(): failed to create registry subscriber: " << e.what() << endl; |
388 | - } |
389 | - } |
390 | - if (subscriber_) |
391 | - { |
392 | - subscriber_->set_message_callback([callback](string const&){ callback(); }); |
393 | - } |
394 | + list_update_subscriber_ = mw_base_->create_subscriber(mw_base_->runtime()->registry_identity()); |
395 | + } |
396 | + return list_update_subscriber_->message_received().connect([callback](string const&){ callback(); }); |
397 | } |
398 | |
399 | } // namespace internal |
400 | |
401 | === modified file 'src/scopes/internal/MWSubscriber.cpp' |
402 | --- src/scopes/internal/MWSubscriber.cpp 2014-05-14 12:57:34 +0000 |
403 | +++ src/scopes/internal/MWSubscriber.cpp 2014-06-03 08:58:50 +0000 |
404 | @@ -35,6 +35,11 @@ |
405 | { |
406 | } |
407 | |
408 | +core::Signal<std::string const&> const& MWSubscriber::message_received() const |
409 | +{ |
410 | + return message_received_; |
411 | +} |
412 | + |
413 | } // namespace internal |
414 | |
415 | } // namespace scopes |
416 | |
417 | === modified file 'src/scopes/internal/RegistryImpl.cpp' |
418 | --- src/scopes/internal/RegistryImpl.cpp 2014-05-27 07:08:33 +0000 |
419 | +++ src/scopes/internal/RegistryImpl.cpp 2014-06-03 08:58:50 +0000 |
420 | @@ -71,9 +71,19 @@ |
421 | return matching_entries; |
422 | } |
423 | |
424 | -void RegistryImpl::set_list_update_callback(std::function<void()> callback) |
425 | -{ |
426 | - fwd()->set_list_update_callback(callback); |
427 | +bool RegistryImpl::is_scope_running(std::string const& scope_id) |
428 | +{ |
429 | + return fwd()->is_scope_running(scope_id); |
430 | +} |
431 | + |
432 | +core::ScopedConnection RegistryImpl::set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback) |
433 | +{ |
434 | + return fwd()->set_scope_state_callback(scope_id, callback); |
435 | +} |
436 | + |
437 | +core::ScopedConnection RegistryImpl::set_list_update_callback(std::function<void()> callback) |
438 | +{ |
439 | + return fwd()->set_list_update_callback(callback); |
440 | } |
441 | |
442 | MWRegistryProxy RegistryImpl::fwd() |
443 | |
444 | === modified file 'src/scopes/internal/RegistryObject.cpp' |
445 | --- src/scopes/internal/RegistryObject.cpp 2014-05-27 09:54:38 +0000 |
446 | +++ src/scopes/internal/RegistryObject.cpp 2014-06-03 08:58:50 +0000 |
447 | @@ -199,6 +199,19 @@ |
448 | return proxy; |
449 | } |
450 | |
451 | +bool RegistryObject::is_scope_running(std::string const& scope_id) |
452 | +{ |
453 | + lock_guard<decltype(mutex_)> lock(mutex_); |
454 | + |
455 | + auto it = scope_processes_.find(scope_id); |
456 | + if (it != scope_processes_.end()) |
457 | + { |
458 | + return it->second.state() != ScopeProcess::ProcessState::Stopped; |
459 | + } |
460 | + |
461 | + throw NotFoundException("RegistryObject::is_scope_process_running(): no such scope: ", scope_id); |
462 | +} |
463 | + |
464 | bool RegistryObject::add_local_scope(std::string const& scope_id, ScopeMetadata const& metadata, |
465 | ScopeExecData const& exec_data) |
466 | { |
467 | @@ -221,7 +234,7 @@ |
468 | return_value = false; |
469 | } |
470 | scopes_.insert(make_pair(scope_id, metadata)); |
471 | - scope_processes_.insert(make_pair(scope_id, ScopeProcess(exec_data))); |
472 | + scope_processes_.insert(make_pair(scope_id, ScopeProcess(exec_data, publisher_))); |
473 | |
474 | if (publisher_) |
475 | { |
476 | @@ -263,19 +276,6 @@ |
477 | remote_registry_ = remote_registry; |
478 | } |
479 | |
480 | -bool RegistryObject::is_scope_running(std::string const& scope_id) |
481 | -{ |
482 | - lock_guard<decltype(mutex_)> lock(mutex_); |
483 | - |
484 | - auto it = scope_processes_.find(scope_id); |
485 | - if (it != scope_processes_.end()) |
486 | - { |
487 | - return it->second.state() != ScopeProcess::ProcessState::Stopped; |
488 | - } |
489 | - |
490 | - throw NotFoundException("RegistryObject::is_scope_process_running(): no such scope: ", scope_id); |
491 | -} |
492 | - |
493 | StateReceiverObject::SPtr RegistryObject::state_receiver() |
494 | { |
495 | return state_receiver_; |
496 | @@ -316,13 +316,15 @@ |
497 | // simply ignore states from scopes the registry does not know about |
498 | } |
499 | |
500 | -RegistryObject::ScopeProcess::ScopeProcess(ScopeExecData exec_data) |
501 | +RegistryObject::ScopeProcess::ScopeProcess(ScopeExecData exec_data, MWPublisher::SPtr publisher) |
502 | : exec_data_(exec_data) |
503 | + , reg_publisher_(publisher) |
504 | { |
505 | } |
506 | |
507 | RegistryObject::ScopeProcess::ScopeProcess(ScopeProcess const& other) |
508 | : exec_data_(other.exec_data_) |
509 | + , reg_publisher_(other.reg_publisher_) |
510 | { |
511 | } |
512 | |
513 | @@ -468,27 +470,51 @@ |
514 | { |
515 | return; |
516 | } |
517 | - else if (state == Running && state_ != Starting) |
518 | - { |
519 | - cout << "RegistryObject::ScopeProcess: Process for scope: \"" << exec_data_.scope_id |
520 | - << "\" started manually" << endl; |
521 | - |
522 | - // Don't update state, treat this scope as not running if a locate() is requested |
523 | - return; |
524 | + else if (state == Running) |
525 | + { |
526 | + if (reg_publisher_) |
527 | + { |
528 | + // Send a "started" message to subscribers to inform them that this scope (topic) has started |
529 | + reg_publisher_->send_message("started", exec_data_.scope_id); |
530 | + } |
531 | + |
532 | + if (state_ != Starting) |
533 | + { |
534 | + cout << "RegistryObject::ScopeProcess: Process for scope: \"" << exec_data_.scope_id |
535 | + << "\" started manually" << endl; |
536 | + |
537 | + // Don't update state, treat this scope as not running if a locate() is requested |
538 | + return; |
539 | + } |
540 | + } |
541 | + else if (state == Stopped) |
542 | + { |
543 | + if (reg_publisher_) |
544 | + { |
545 | + // Send a "stopped" message to subscribers to inform them that this scope (topic) has stopped |
546 | + reg_publisher_->send_message("stopped", exec_data_.scope_id); |
547 | + } |
548 | + |
549 | + if (state_ != Stopping) |
550 | + { |
551 | + cerr << "RegistryObject::ScopeProcess: Scope: \"" << exec_data_.scope_id |
552 | + << "\" closed unexpectedly. Either the process crashed or was killed forcefully." << endl; |
553 | + } |
554 | } |
555 | else if (state == Stopping && state_ != Running) |
556 | { |
557 | + if (reg_publisher_) |
558 | + { |
559 | + // Send a "stopped" message to subscribers to inform them that this scope (topic) has stopped |
560 | + reg_publisher_->send_message("stopped", exec_data_.scope_id); |
561 | + } |
562 | + |
563 | cout << "RegistryObject::ScopeProcess: Manually started process for scope: \"" |
564 | << exec_data_.scope_id << "\" terminated" << endl; |
565 | |
566 | // Don't update state, treat this scope as not running if a locate() is requested |
567 | return; |
568 | } |
569 | - else if (state == Stopped && state_ != Stopping) |
570 | - { |
571 | - cerr << "RegistryObject::ScopeProcess: Scope: \"" << exec_data_.scope_id |
572 | - << "\" closed unexpectedly. Either the process crashed or was killed forcefully." << endl; |
573 | - } |
574 | state_ = state; |
575 | state_change_cond_.notify_all(); |
576 | } |
577 | |
578 | === modified file 'src/scopes/internal/smartscopes/SSRegistryObject.cpp' |
579 | --- src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-05-16 14:29:11 +0000 |
580 | +++ src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-06-03 08:58:50 +0000 |
581 | @@ -127,6 +127,11 @@ |
582 | throw internal::RegistryException("SSRegistryObject::locate(): operation not available"); |
583 | } |
584 | |
585 | +bool SSRegistryObject::is_scope_running(std::string const&) |
586 | +{ |
587 | + throw internal::RegistryException("SSRegistryObject::is_scope_running(): operation not available"); |
588 | +} |
589 | + |
590 | bool SSRegistryObject::has_scope(std::string const& scope_id) const |
591 | { |
592 | std::lock_guard<std::mutex> lock(scopes_mutex_); |
593 | |
594 | === modified file 'src/scopes/internal/zmq_middleware/RegistryI.cpp' |
595 | --- src/scopes/internal/zmq_middleware/RegistryI.cpp 2014-05-29 15:41:42 +0000 |
596 | +++ src/scopes/internal/zmq_middleware/RegistryI.cpp 2014-06-03 08:58:50 +0000 |
597 | @@ -68,7 +68,8 @@ |
598 | RegistryI::RegistryI(RegistryObjectBase::SPtr const& ro) : |
599 | ServantBase(ro, { { "get_metadata", bind(&RegistryI::get_metadata_, this, _1, _2, _3) }, |
600 | { "list", bind(&RegistryI::list_, this, _1, _2, _3) }, |
601 | - { "locate", bind(&RegistryI::locate_, this, _1, _2, _3) } }) |
602 | + { "locate", bind(&RegistryI::locate_, this, _1, _2, _3) }, |
603 | + { "is_scope_running", bind(&RegistryI::is_scope_running_, this, _1, _2, _3) } }) |
604 | |
605 | { |
606 | } |
607 | @@ -151,6 +152,28 @@ |
608 | } |
609 | } |
610 | |
611 | +void RegistryI::is_scope_running_(Current const&, |
612 | + capnp::AnyPointer::Reader& in_params, |
613 | + capnproto::Response::Builder& r) |
614 | +{ |
615 | + auto req = in_params.getAs<capnproto::Registry::IsScopeRunningRequest>(); |
616 | + string scope_id = req.getIdentity().cStr(); |
617 | + auto delegate = dynamic_pointer_cast<RegistryObjectBase>(del()); |
618 | + try |
619 | + { |
620 | + auto is_running = delegate->is_scope_running(scope_id); |
621 | + r.setStatus(capnproto::ResponseStatus::SUCCESS); |
622 | + auto is_scope_running_response = r.initPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().initResponse(); |
623 | + is_scope_running_response.setReturnValue(is_running); |
624 | + } |
625 | + catch (NotFoundException const& e) |
626 | + { |
627 | + r.setStatus(capnproto::ResponseStatus::USER_EXCEPTION); |
628 | + auto get_metadata_response = r.initPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().initResponse(); |
629 | + get_metadata_response.initNotFoundException().setIdentity(e.name().c_str()); |
630 | + } |
631 | +} |
632 | + |
633 | } // namespace zmq_middleware |
634 | |
635 | } // namespace internal |
636 | |
637 | === modified file 'src/scopes/internal/zmq_middleware/ZmqRegistry.cpp' |
638 | --- src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-05-07 05:54:20 +0000 |
639 | +++ src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-06-03 08:58:50 +0000 |
640 | @@ -187,6 +187,40 @@ |
641 | } |
642 | } |
643 | } |
644 | + |
645 | +bool ZmqRegistry::is_scope_running(std::string const& scope_id) |
646 | +{ |
647 | + capnp::MallocMessageBuilder request_builder; |
648 | + auto request = make_request_(request_builder, "is_scope_running"); |
649 | + auto in_params = request.initInParams().getAs<capnproto::Registry::IsScopeRunningRequest>(); |
650 | + in_params.setIdentity(scope_id.c_str()); |
651 | + |
652 | + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); }); |
653 | + auto receiver = future.get(); |
654 | + auto segments = receiver.receive(); |
655 | + capnp::SegmentArrayMessageReader reader(segments); |
656 | + auto response = reader.getRoot<capnproto::Response>(); |
657 | + throw_if_runtime_exception(response); |
658 | + |
659 | + auto is_scope_running_response = response.getPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().getResponse(); |
660 | + switch (is_scope_running_response.which()) |
661 | + { |
662 | + case capnproto::Registry::IsScopeRunningResponse::Response::RETURN_VALUE: |
663 | + { |
664 | + return is_scope_running_response.getReturnValue(); |
665 | + } |
666 | + case capnproto::Registry::IsScopeRunningResponse::Response::NOT_FOUND_EXCEPTION: |
667 | + { |
668 | + auto ex = is_scope_running_response.getNotFoundException(); |
669 | + throw NotFoundException("Registry::is_scope_running(): no such scope", ex.getIdentity().cStr()); |
670 | + } |
671 | + default: |
672 | + { |
673 | + throw MiddlewareException("Registry::is_scope_running(): unknown user exception"); |
674 | + } |
675 | + } |
676 | +} |
677 | + |
678 | } // namespace zmq_middleware |
679 | |
680 | } // namespace internal |
681 | |
682 | === modified file 'src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp' |
683 | --- src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 2014-05-21 13:01:10 +0000 |
684 | +++ src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 2014-06-03 08:58:50 +0000 |
685 | @@ -44,7 +44,6 @@ |
686 | , topic_(topic) |
687 | , thread_state_(NotRunning) |
688 | , thread_exception_(nullptr) |
689 | - , callback_(nullptr) |
690 | { |
691 | // Validate publisher_id |
692 | if (publisher_id.find('/') != std::string::npos) |
693 | @@ -91,7 +90,6 @@ |
694 | { |
695 | { |
696 | std::lock_guard<std::mutex> lock(mutex_); |
697 | - callback_ = nullptr; |
698 | thread_stopper_ = nullptr; |
699 | } |
700 | |
701 | @@ -106,12 +104,6 @@ |
702 | return endpoint_; |
703 | } |
704 | |
705 | -void ZmqSubscriber::set_message_callback(SubscriberCallback callback) |
706 | -{ |
707 | - std::lock_guard<std::mutex> lock(mutex_); |
708 | - callback_ = callback; |
709 | -} |
710 | - |
711 | void ZmqSubscriber::subscriber_thread() |
712 | { |
713 | try |
714 | @@ -151,14 +143,11 @@ |
715 | |
716 | // Discard the message if no callback is set |
717 | std::lock_guard<std::mutex> lock(mutex_); |
718 | - if (callback_) |
719 | + // Message should arrive in the format: "<topic>:<message>" |
720 | + if (message.length() > topic_.length() && |
721 | + message[topic_.length()] == ':') |
722 | { |
723 | - // Message should arrive in the format: "<topic>:<message>" |
724 | - if (message.length() > topic_.length() && |
725 | - message[topic_.length()] == ':') |
726 | - { |
727 | - callback_(message.substr(topic_.length() + 1)); |
728 | - } |
729 | + message_received_(message.substr(topic_.length() + 1)); |
730 | } |
731 | } |
732 | else if(poller.has_input(stop_socket)) |
733 | @@ -175,7 +164,6 @@ |
734 | catch (...) |
735 | { |
736 | std::lock_guard<std::mutex> lock(mutex_); |
737 | - callback_ = nullptr; |
738 | thread_stopper_ = nullptr; |
739 | thread_exception_ = std::current_exception(); |
740 | thread_state_ = Stopped; |
741 | |
742 | === modified file 'src/scopes/internal/zmq_middleware/capnproto/Registry.capnp' |
743 | --- src/scopes/internal/zmq_middleware/capnproto/Registry.capnp 2014-04-03 12:57:25 +0000 |
744 | +++ src/scopes/internal/zmq_middleware/capnproto/Registry.capnp 2014-06-03 08:58:50 +0000 |
745 | @@ -80,3 +80,17 @@ |
746 | registryException @2 : RegistryException; |
747 | } |
748 | } |
749 | + |
750 | +struct IsScopeRunningRequest |
751 | +{ |
752 | + identity @0 : Text; |
753 | +} |
754 | + |
755 | +struct IsScopeRunningResponse |
756 | +{ |
757 | + response : union |
758 | + { |
759 | + returnValue @0 : Bool; |
760 | + notFoundException @1 : NotFoundException; |
761 | + } |
762 | +} |
763 | |
764 | === modified file 'test/gtest/scopes/Registry/Registry_test.cpp' |
765 | --- test/gtest/scopes/Registry/Registry_test.cpp 2014-05-27 12:46:25 +0000 |
766 | +++ test/gtest/scopes/Registry/Registry_test.cpp 2014-06-03 08:58:50 +0000 |
767 | @@ -64,6 +64,7 @@ |
768 | auto now = std::chrono::steady_clock::now(); |
769 | auto expiry_time = now + std::chrono::seconds(5); |
770 | EXPECT_TRUE(cond_.wait_until(lock, expiry_time, [this]{ return done_; })) << "finished message not delivered"; |
771 | + done_ = false; |
772 | return finished_ok_; |
773 | } |
774 | |
775 | @@ -103,43 +104,115 @@ |
776 | EXPECT_EQ("scope-B.HotKey", meta.hot_key()); |
777 | EXPECT_EQ("scope-B.SearchHint", meta.search_hint()); |
778 | EXPECT_EQ(TEST_RUNTIME_PATH "/scopes/testscopeB", meta.scope_directory()); |
779 | - |
780 | - auto sp = meta.proxy(); |
781 | +} |
782 | + |
783 | +TEST(Registry, scope_state_notify) |
784 | +{ |
785 | + bool update_received = false; |
786 | + bool testscopeA_state = false; |
787 | + bool testscopeB_state = false; |
788 | + std::mutex mutex; |
789 | + std::condition_variable cond; |
790 | + |
791 | + Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE); |
792 | + RegistryProxy r = rt->registry(); |
793 | + |
794 | + // Configure testscopeA scope_state_callback |
795 | + auto connA = r->set_scope_state_callback("testscopeA", [&update_received, &testscopeA_state, &mutex, &cond](bool is_running) |
796 | + { |
797 | + std::lock_guard<std::mutex> lock(mutex); |
798 | + update_received = true; |
799 | + testscopeA_state = is_running; |
800 | + cond.notify_one(); |
801 | + }); |
802 | + // Configure testscopeB scope_state_callback |
803 | + auto connB = r->set_scope_state_callback("testscopeB", [&update_received, &testscopeB_state, &mutex, &cond](bool is_running) |
804 | + { |
805 | + std::lock_guard<std::mutex> lock(mutex); |
806 | + update_received = true; |
807 | + testscopeB_state = is_running; |
808 | + cond.notify_one(); |
809 | + }); |
810 | + auto wait_for_state_update = [&update_received, &mutex, &cond] |
811 | + { |
812 | + // Wait for an update notification |
813 | + std::unique_lock<std::mutex> lock(mutex); |
814 | + bool success = cond.wait_for(lock, std::chrono::milliseconds(500), [&update_received] { return update_received; }); |
815 | + update_received = false; |
816 | + return success; |
817 | + }; |
818 | |
819 | auto receiver = std::make_shared<Receiver>(); |
820 | SearchListenerBase::SPtr reply(receiver); |
821 | SearchMetadata metadata("C", "desktop"); |
822 | |
823 | + auto meta = r->get_metadata("testscopeA"); |
824 | + auto sp = meta.proxy(); |
825 | + |
826 | + // testscopeA should not be running at this point |
827 | + EXPECT_FALSE(r->is_scope_running("testscopeA")); |
828 | + EXPECT_FALSE(wait_for_state_update()); |
829 | + |
830 | + // search would fail if testscopeA can't be executed |
831 | + auto ctrl = sp->search("foo", metadata, reply); |
832 | + EXPECT_TRUE(receiver->wait_until_finished()); |
833 | + |
834 | + // testscopeA should now be running |
835 | + EXPECT_TRUE(wait_for_state_update()); |
836 | + EXPECT_TRUE(testscopeA_state); |
837 | + EXPECT_TRUE(r->is_scope_running("testscopeA")); |
838 | + |
839 | + meta = r->get_metadata("testscopeB"); |
840 | + sp = meta.proxy(); |
841 | + |
842 | + // testscopeB should not be running at this point |
843 | + EXPECT_FALSE(r->is_scope_running("testscopeB")); |
844 | + EXPECT_FALSE(wait_for_state_update()); |
845 | + |
846 | // search would fail if testscopeB can't be executed |
847 | - auto ctrl = sp->search("foo", metadata, reply); |
848 | + ctrl = sp->search("foo", metadata, reply); |
849 | EXPECT_TRUE(receiver->wait_until_finished()); |
850 | + |
851 | + // testscopeB should now be running |
852 | + EXPECT_TRUE(wait_for_state_update()); |
853 | + EXPECT_TRUE(testscopeB_state); |
854 | + EXPECT_TRUE(r->is_scope_running("testscopeB")); |
855 | + |
856 | + // check now that we get a callback when testscopeB terminates (timed out after 2s) |
857 | + std::this_thread::sleep_for(std::chrono::seconds{3}); |
858 | + EXPECT_TRUE(wait_for_state_update()); |
859 | + EXPECT_FALSE(testscopeB_state); |
860 | + EXPECT_FALSE(r->is_scope_running("testscopeB")); |
861 | } |
862 | |
863 | -TEST(Registry, update_notify) |
864 | +TEST(Registry, list_update_notify) |
865 | { |
866 | - bool update_received_ = false; |
867 | - std::mutex mutex_; |
868 | - std::condition_variable cond_; |
869 | + bool update_received = false; |
870 | + std::mutex mutex; |
871 | + std::condition_variable cond; |
872 | |
873 | Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE); |
874 | RegistryProxy r = rt->registry(); |
875 | |
876 | // Configure registry update callback |
877 | - r->set_list_update_callback([&update_received_, &mutex_, &cond_] |
878 | + auto conn = r->set_list_update_callback([&update_received, &mutex, &cond] |
879 | { |
880 | - std::lock_guard<std::mutex> lock(mutex_); |
881 | - update_received_ = true; |
882 | - cond_.notify_one(); |
883 | + std::lock_guard<std::mutex> lock(mutex); |
884 | + update_received = true; |
885 | + cond.notify_one(); |
886 | }); |
887 | - auto wait_for_update = [&update_received_, &mutex_, &cond_] |
888 | + auto wait_for_update = [&update_received, &mutex, &cond] |
889 | { |
890 | // Flush out update notifications |
891 | - std::unique_lock<std::mutex> lock(mutex_); |
892 | - while (cond_.wait_for(lock, std::chrono::milliseconds(500), [&update_received_] { return update_received_; })) |
893 | + std::unique_lock<std::mutex> lock(mutex); |
894 | + bool success = false; |
895 | + while (cond.wait_for(lock, std::chrono::milliseconds(500), [&update_received] { return update_received; })) |
896 | { |
897 | - update_received_ = false; |
898 | + success = true; |
899 | + update_received = false; |
900 | } |
901 | - update_received_ = false; |
902 | + update_received = false; |
903 | + return success; |
904 | }; |
905 | |
906 | system::error_code ec; |
907 | @@ -156,7 +229,7 @@ |
908 | std::cout << "Move testscopeC into the scopes folder" << std::endl; |
909 | filesystem::rename(TEST_RUNTIME_PATH "/other_scopes/testscopeC", TEST_RUNTIME_PATH "/scopes/testscopeC", ec); |
910 | ASSERT_EQ("Success", ec.message()); |
911 | - wait_for_update(); |
912 | + EXPECT_TRUE(wait_for_update()); |
913 | |
914 | // Now check that we have 3 scopes registered |
915 | list = r->list(); |
916 | @@ -170,7 +243,7 @@ |
917 | std::cout << "Make a symlink to testscopeD in the scopes folder" << std::endl; |
918 | filesystem::create_symlink(TEST_RUNTIME_PATH "/other_scopes/testscopeD", TEST_RUNTIME_PATH "/scopes/testscopeD", ec); |
919 | ASSERT_EQ("Success", ec.message()); |
920 | - wait_for_update(); |
921 | + EXPECT_TRUE(wait_for_update()); |
922 | |
923 | // Now check that we have 4 scopes registered |
924 | list = r->list(); |
925 | @@ -184,7 +257,7 @@ |
926 | std::cout << "Move testscopeC back into the other_scopes folder" << std::endl; |
927 | filesystem::rename(TEST_RUNTIME_PATH "/scopes/testscopeC", TEST_RUNTIME_PATH "/other_scopes/testscopeC", ec); |
928 | ASSERT_EQ("Success", ec.message()); |
929 | - wait_for_update(); |
930 | + EXPECT_TRUE(wait_for_update()); |
931 | |
932 | // Now check that we have 3 scopes registered again |
933 | list = r->list(); |
934 | @@ -198,7 +271,7 @@ |
935 | std::cout << "Remove symlink to testscopeD from the scopes folder" << std::endl; |
936 | filesystem::remove(TEST_RUNTIME_PATH "/scopes/testscopeD", ec); |
937 | ASSERT_EQ("Success", ec.message()); |
938 | - wait_for_update(); |
939 | + EXPECT_TRUE(wait_for_update()); |
940 | |
941 | // Now check that we are back to having 2 scopes registered |
942 | list = r->list(); |
943 | @@ -212,6 +285,7 @@ |
944 | std::cout << "Make a folder in scopes named \"testfolder\"" << std::endl; |
945 | filesystem::create_directory(TEST_RUNTIME_PATH "/scopes/testfolder", ec); |
946 | ASSERT_EQ("Success", ec.message()); |
947 | + EXPECT_FALSE(wait_for_update()); |
948 | |
949 | // Check that no scopes were registered |
950 | list = r->list(); |
951 | @@ -225,7 +299,7 @@ |
952 | std::cout << "Make a symlink to testscopeC.ini in testfolder" << std::endl; |
953 | filesystem::create_symlink(TEST_RUNTIME_PATH "/other_scopes/testscopeC/testscopeC.ini", TEST_RUNTIME_PATH "/scopes/testfolder/testscopeC.ini", ec); |
954 | ASSERT_EQ("Success", ec.message()); |
955 | - wait_for_update(); |
956 | + EXPECT_TRUE(wait_for_update()); |
957 | |
958 | // Now check that we have 3 scopes registered |
959 | list = r->list(); |
960 | @@ -239,7 +313,7 @@ |
961 | std::cout << "Remove testfolder" << std::endl; |
962 | filesystem::remove_all(TEST_RUNTIME_PATH "/scopes/testfolder", ec); |
963 | ASSERT_EQ("Success", ec.message()); |
964 | - wait_for_update(); |
965 | + EXPECT_TRUE(wait_for_update()); |
966 | |
967 | // Now check that we are back to having 2 scopes registered |
968 | list = r->list(); |
969 | |
970 | === modified file 'test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp' |
971 | --- test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 2014-05-20 04:20:46 +0000 |
972 | +++ test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 2014-06-03 08:58:50 +0000 |
973 | @@ -167,16 +167,16 @@ |
974 | |
975 | // Create a few subscribers |
976 | auto subscriber1 = mw.create_subscriber("testpublisher", "testtopic1"); |
977 | - subscriber1->set_message_callback(std::bind(&SubMsgReceiver::receive1, &message_receiver, _1)); |
978 | + subscriber1->message_received().connect(std::bind(&SubMsgReceiver::receive1, &message_receiver, _1)); |
979 | |
980 | auto subscriber2 = mw.create_subscriber("testpublisher", "testtopic2"); |
981 | - subscriber2->set_message_callback(std::bind(&SubMsgReceiver::receive2, &message_receiver, _1)); |
982 | + subscriber2->message_received().connect(std::bind(&SubMsgReceiver::receive2, &message_receiver, _1)); |
983 | |
984 | auto subscriber3 = mw.create_subscriber("testpublisher", ""); |
985 | - subscriber3->set_message_callback(std::bind(&SubMsgReceiver::receive3, &message_receiver, _1)); |
986 | + subscriber3->message_received().connect(std::bind(&SubMsgReceiver::receive3, &message_receiver, _1)); |
987 | |
988 | auto subscriber4 = mw.create_subscriber("testpublisher2", "testtopic4"); |
989 | - subscriber4->set_message_callback(std::bind(&SubMsgReceiver::receive4, &message_receiver, _1)); |
990 | + subscriber4->message_received().connect(std::bind(&SubMsgReceiver::receive4, &message_receiver, _1)); |
991 | |
992 | // Give the subscribers some time to connect |
993 | std::this_thread::sleep_for(std::chrono::milliseconds(500)); |
FAILED: Continuous integration, rev:370 jenkins. qa.ubuntu. com/job/ unity-scopes- api-devel- ci/619/ jenkins. qa.ubuntu. com/job/ unity-scopes- api-devel- utopic- amd64-ci/ 173/console jenkins. qa.ubuntu. com/job/ unity-scopes- api-devel- utopic- armhf-ci/ 171/console jenkins. qa.ubuntu. com/job/ unity-scopes- api-devel- utopic- i386-ci/ 171/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- scopes- api-devel- ci/619/ rebuild
http://