Merge lp:~unity-api-team/unity-scopes-api/click-store-support into lp:unity-scopes-api

Proposed by Pete Woods
Status: Merged
Merged at revision: 211
Proposed branch: lp:~unity-api-team/unity-scopes-api/click-store-support
Merge into: lp:unity-scopes-api
Diff against target: 2465 lines (+1355/-216)
45 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+9/-0)
debian/control (+2/-1)
debian/libunity-scopes1.symbols (+4/-3)
include/unity/scopes/Registry.h (+29/-1)
include/unity/scopes/internal/MWRegistry.h (+11/-0)
include/unity/scopes/internal/MWSubscriber.h (+4/-3)
include/unity/scopes/internal/RegistryImpl.h (+4/-0)
include/unity/scopes/internal/RegistryObject.h (+9/-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 (+3/-8)
include/unity/scopes/testing/MockRegistry.h (+9/-0)
scoperegistry/CMakeLists.txt (+2/-0)
scoperegistry/DirWatcher.cpp (+272/-0)
scoperegistry/DirWatcher.h (+79/-0)
scoperegistry/FindFiles.cpp (+35/-23)
scoperegistry/FindFiles.h (+17/-9)
scoperegistry/ScopesWatcher.cpp (+184/-0)
scoperegistry/ScopesWatcher.h (+57/-0)
scoperegistry/scoperegistry.cpp (+136/-100)
src/scopes/internal/MWRegistry.cpp (+23/-1)
src/scopes/internal/MWSubscriber.cpp (+5/-0)
src/scopes/internal/RegistryImpl.cpp (+15/-0)
src/scopes/internal/RegistryObject.cpp (+93/-21)
src/scopes/internal/smartscopes/SSRegistryObject.cpp (+5/-0)
src/scopes/internal/zmq_middleware/ObjectAdapter.cpp (+3/-3)
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 (+13/-18)
src/scopes/internal/zmq_middleware/capnproto/Registry.capnp (+14/-0)
test/gtest/scopes/CMakeLists.txt (+3/-3)
test/gtest/scopes/Registry/CMakeLists.txt (+1/-0)
test/gtest/scopes/Registry/Registry_test.cpp (+216/-5)
test/gtest/scopes/Registry/other_scopes/CMakeLists.txt (+2/-0)
test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt (+1/-0)
test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in (+8/-0)
test/gtest/scopes/Registry/other_scopes/testscopeD/CMakeLists.txt (+1/-0)
test/gtest/scopes/Registry/other_scopes/testscopeD/testscopeD.ini.in (+8/-0)
test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp (+1/-1)
test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt (+1/-1)
test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp (+4/-4)
test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp (+6/-6)
To merge this branch: bzr merge lp:~unity-api-team/unity-scopes-api/click-store-support
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Unity Team Pending
Review via email: mp+221679@code.launchpad.net

Commit message

Click store support

Description of the change

Click store support

To post a comment you must log in.
211. By Pete Woods

Merge devel

212. By Marcus Tomlinson

Introduced Dir/ScopesWatcher classes to watch for updates to the scope install directories, and updated all relevant registry code to propagate an update pub/sub message via middleware.

Approved by PS Jenkins bot, Michi Henning.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
213. By MichaƂ Sawicz

Revert to :any qualifier for python3 since LP recipes don't support it still.

Approved by PS Jenkins bot.

214. By Pete Woods

Bump micro version

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
215. By Marcus Tomlinson

Introduced is_scope_running() and set_scope_state_callback() to Registry, added return values to set_*_callback() methods (to disconnect callback on destruction), and updated tests.

Approved by Pete Woods, PS Jenkins bot.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-05-22 08:45:05 +0000
+++ CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -180,7 +180,7 @@
180# API version180# API version
181set(UNITY_SCOPES_MAJOR 0)181set(UNITY_SCOPES_MAJOR 0)
182set(UNITY_SCOPES_MINOR 4)182set(UNITY_SCOPES_MINOR 4)
183set(UNITY_SCOPES_MICRO 7)183set(UNITY_SCOPES_MICRO 8)
184184
185# Version for testing, with all symbols visible185# Version for testing, with all symbols visible
186set(UNITY_SCOPES_TEST_LIB ${UNITY_SCOPES_LIB}-test)186set(UNITY_SCOPES_TEST_LIB ${UNITY_SCOPES_LIB}-test)
187187
=== modified file 'debian/changelog'
--- debian/changelog 2014-05-22 09:58:34 +0000
+++ debian/changelog 2014-06-03 09:42:46 +0000
@@ -1,3 +1,12 @@
1unity-scopes-api (0.4.8-0ubuntu1) UNRELEASED; urgency=medium
2
3 [ Marcus Tomlinson ]
4 * Introduced Dir/ScopesWatcher classes to watch for updates to the scope install directories.
5 * Updated all relevant registry classes to propagate an update pub/sub message via middleware.
6 * Added is_scope_running(), set_scope_state_callback() and set_update_callback() to Registry.
7
8 -- Marcus Tomlinson <marcustomlinson@ubuntu> Wed, 28 May 2014 17:08:45 +0200
9
1unity-scopes-api (0.4.7+14.10.20140522-0ubuntu1) utopic; urgency=low10unity-scopes-api (0.4.7+14.10.20140522-0ubuntu1) utopic; urgency=low
211
3 [ Ubuntu daily release ]12 [ Ubuntu daily release ]
413
=== modified file 'debian/control'
--- debian/control 2014-05-22 08:45:05 +0000
+++ debian/control 2014-06-03 09:42:46 +0000
@@ -8,7 +8,7 @@
8 google-mock,8 google-mock,
9 graphviz,9 graphviz,
10 pkg-config,10 pkg-config,
11 python3:native,11 python3:any,
12 capnproto,12 capnproto,
13 libapparmor-dev,13 libapparmor-dev,
14 libprocess-cpp-dev (>= 1.0.1),14 libprocess-cpp-dev (>= 1.0.1),
@@ -49,6 +49,7 @@
49Multi-Arch: same49Multi-Arch: same
50Pre-Depends: ${misc:Pre-Depends},50Pre-Depends: ${misc:Pre-Depends},
51Depends: libunity-scopes1 (= ${binary:Version}),51Depends: libunity-scopes1 (= ${binary:Version}),
52 libproperties-cpp-dev,
52 libunity-api-dev,53 libunity-api-dev,
53 ${misc:Depends},54 ${misc:Depends},
54Description: Header files for Unity scopes API55Description: Header files for Unity scopes API
5556
=== modified file 'debian/libunity-scopes1.symbols'
--- debian/libunity-scopes1.symbols 2014-05-22 09:58:32 +0000
+++ debian/libunity-scopes1.symbols 2014-06-03 09:42:46 +0000
@@ -411,6 +411,7 @@
411 (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.1411 (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
412 (c++)"unity::scopes::internal::smartscopes::SSScopeObject::~SSScopeObject()@Base" 0.4.0+14.04.20140312.1412 (c++)"unity::scopes::internal::smartscopes::SSScopeObject::~SSScopeObject()@Base" 0.4.0+14.04.20140312.1
413 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::refresh_thread()@Base" 0.4.0+14.04.20140312.1413 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::refresh_thread()@Base" 0.4.0+14.04.20140312.1
414 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::is_scope_running(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
414 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::get_remote_scopes()@Base" 0.4.0+14.04.20140312.1415 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::get_remote_scopes()@Base" 0.4.0+14.04.20140312.1
415 (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.20140324416 (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
416 (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.1417 (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
@@ -431,9 +432,9 @@
431 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::exec(core::posix::ChildProcess::DeathObserver&, std::shared_ptr<unity::scopes::internal::Executor>)@Base" 0.4.3+14.10.20140428432 (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
432 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill(std::unique_lock<std::mutex>&)@Base" 0.4.2+14.04.20140404.2433 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill(std::unique_lock<std::mutex>&)@Base" 0.4.2+14.04.20140404.2
433 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill()@Base" 0.4.2+14.04.20140404.2434 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::kill()@Base" 0.4.2+14.04.20140404.2
434 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData)@Base" 0.4.2+14.04.20140404.2435 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData, std::shared_ptr<unity::scopes::internal::MWPublisher>)@Base" 0replaceme
435 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2436 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2
436 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData)@Base" 0.4.2+14.04.20140404.2437 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeExecData, std::shared_ptr<unity::scopes::internal::MWPublisher>)@Base" 0replaceme
437 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2438 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::ScopeProcess(unity::scopes::internal::RegistryObject::ScopeProcess const&)@Base" 0.4.2+14.04.20140404.2
438 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::~ScopeProcess()@Base" 0.4.2+14.04.20140404.2439 (c++)"unity::scopes::internal::RegistryObject::ScopeProcess::~ScopeProcess()@Base" 0.4.2+14.04.20140404.2
439 (c++)"unity::scopes::internal::RegistryObject::ScopeExecData::~ScopeExecData()@Base" 0.4.2+14.04.20140404.2440 (c++)"unity::scopes::internal::RegistryObject::ScopeExecData::~ScopeExecData()@Base" 0.4.2+14.04.20140404.2
@@ -445,7 +446,7 @@
445 (c++)"unity::scopes::internal::RegistryObject::remove_local_scope(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1446 (c++)"unity::scopes::internal::RegistryObject::remove_local_scope(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
446 (c++)"unity::scopes::internal::RegistryObject::set_remote_registry(std::shared_ptr<unity::scopes::internal::MWRegistry> const&)@Base" 0.4.0+14.04.20140312.1447 (c++)"unity::scopes::internal::RegistryObject::set_remote_registry(std::shared_ptr<unity::scopes::internal::MWRegistry> const&)@Base" 0.4.0+14.04.20140312.1
447 (c++)"unity::scopes::internal::RegistryObject::locate(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1448 (c++)"unity::scopes::internal::RegistryObject::locate(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
448 (c++)"unity::scopes::internal::RegistryObject::RegistryObject(core::posix::ChildProcess::DeathObserver&, std::shared_ptr<unity::scopes::internal::Executor> const&)@Base" 0.4.3+14.10.20140428449 (c++)"unity::scopes::internal::RegistryObject::RegistryObject(core::posix::ChildProcess::DeathObserver&, std::shared_ptr<unity::scopes::internal::Executor> const&, std::shared_ptr<unity::scopes::internal::MiddlewareBase>)@Base" 0replaceme
449 (c++)"unity::scopes::internal::RegistryObject::~RegistryObject()@Base" 0.4.0+14.04.20140312.1450 (c++)"unity::scopes::internal::RegistryObject::~RegistryObject()@Base" 0.4.0+14.04.20140312.1
450 (c++)"unity::scopes::internal::MiddlewareFactory::MiddlewareData::~MiddlewareData()@Base" 0.4.0+14.04.20140312.1451 (c++)"unity::scopes::internal::MiddlewareFactory::MiddlewareData::~MiddlewareData()@Base" 0.4.0+14.04.20140312.1
451 (c++)"unity::scopes::internal::MiddlewareFactory::to_kind(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1452 (c++)"unity::scopes::internal::MiddlewareFactory::to_kind(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
452453
=== modified file 'include/unity/scopes/Registry.h'
--- include/unity/scopes/Registry.h 2014-05-19 08:26:40 +0000
+++ include/unity/scopes/Registry.h 2014-06-03 09:42:46 +0000
@@ -19,6 +19,7 @@
19#ifndef UNITY_SCOPES_REGISTRY_H19#ifndef UNITY_SCOPES_REGISTRY_H
20#define UNITY_SCOPES_REGISTRY_H20#define UNITY_SCOPES_REGISTRY_H
2121
22#include <core/signal.h>
22#include <unity/scopes/Object.h>23#include <unity/scopes/Object.h>
23#include <unity/scopes/RegistryProxyFwd.h>24#include <unity/scopes/RegistryProxyFwd.h>
24#include <unity/scopes/ScopeMetadata.h>25#include <unity/scopes/ScopeMetadata.h>
@@ -56,8 +57,9 @@
5657
57 /**58 /**
58 \brief Returns the metadata for the scope with the given ID.59 \brief Returns the metadata for the scope with the given ID.
60 \param scope_id The ID of the scope from which we wish to retrieve metadata.
59 \return The metadata for the scope.61 \return The metadata for the scope.
60 \throws NotFoundException if no scope with the given name exists.62 \throws NotFoundException if no scope with the given ID exists.
61 */63 */
62 virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0;64 virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0;
6365
@@ -74,6 +76,32 @@
74 */76 */
75 virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) = 0;77 virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) = 0;
7678
79 /**
80 \brief Returns whether a scope is currently running or not.
81 \param scope_id The ID of the scope from which we wish to retrieve state.
82 \return True if the scope is running, and False if it is not running.
83 \throws NotFoundException if no scope with the given ID exists.
84 */
85 virtual bool is_scope_running(std::string const& scope_id) = 0;
86
87 /**
88 \brief Assigns a callback method to be executed when a scope's running state (started / stopped) changes.
89 \param scope_id The ID of the scope from which we wish to retrieve state changes.
90 \param callback The function object that is invoked when a scope changes running state.
91 \throws MiddlewareException if the registry subscriber failed to initialize.
92 */
93 virtual core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool is_running)> callback) = 0;
94
95 /**
96 \brief Assigns a callback method to be executed when the registry's scope list changes.
97
98 Note: Upon receiving this callback, you should retrieve the updated scopes list via the list() method if
99 you wish to retain synchronisation between client and server.
100 \param callback The function object that is invoked when an update occurs.
101 \throws MiddlewareException if the registry subscriber failed to initialize.
102 */
103 virtual core::ScopedConnection set_list_update_callback(std::function<void()> callback) = 0;
104
77protected:105protected:
78 /// @cond106 /// @cond
79 Registry();107 Registry();
80108
=== modified file 'include/unity/scopes/internal/MWRegistry.h'
--- include/unity/scopes/internal/MWRegistry.h 2014-04-03 12:57:25 +0000
+++ include/unity/scopes/internal/MWRegistry.h 2014-06-03 09:42:46 +0000
@@ -20,6 +20,7 @@
20#define UNITY_SCOPES_INTERNAL_MWREGISTRY_H20#define UNITY_SCOPES_INTERNAL_MWREGISTRY_H
2121
22#include <unity/scopes/internal/MWObjectProxy.h>22#include <unity/scopes/internal/MWObjectProxy.h>
23#include <unity/scopes/internal/MWSubscriber.h>
23#include <unity/scopes/Registry.h>24#include <unity/scopes/Registry.h>
24#include <unity/scopes/ScopeMetadata.h>25#include <unity/scopes/ScopeMetadata.h>
2526
@@ -39,11 +40,21 @@
39 virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0;40 virtual ScopeMetadata get_metadata(std::string const& scope_id) = 0;
40 virtual MetadataMap list() = 0;41 virtual MetadataMap list() = 0;
41 virtual ObjectProxy locate(std::string const& identity) = 0;42 virtual ObjectProxy locate(std::string const& identity) = 0;
43 virtual bool is_scope_running(std::string const& scope_id) = 0;
4244
43 virtual ~MWRegistry();45 virtual ~MWRegistry();
4446
47 // Local operations
48 core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback);
49 core::ScopedConnection set_list_update_callback(std::function<void()> callback);
50
45protected:51protected:
46 MWRegistry(MiddlewareBase* mw_base);52 MWRegistry(MiddlewareBase* mw_base);
53
54private:
55 MiddlewareBase* mw_base_;
56 MWSubscriber::UPtr list_update_subscriber_;
57 std::map<std::string, MWSubscriber::UPtr> scope_state_subscribers_;
47};58};
4859
49} // namespace internal60} // namespace internal
5061
=== modified file 'include/unity/scopes/internal/MWSubscriber.h'
--- include/unity/scopes/internal/MWSubscriber.h 2014-05-19 05:15:06 +0000
+++ include/unity/scopes/internal/MWSubscriber.h 2014-06-03 09:42:46 +0000
@@ -19,6 +19,7 @@
19#ifndef UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H19#ifndef UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H
20#define UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H20#define UNITY_SCOPES_INTERNAL_MWSUBSCRIBER_H
2121
22#include <core/signal.h>
22#include <unity/util/DefinesPtrs.h>23#include <unity/util/DefinesPtrs.h>
23#include <unity/util/NonCopyable.h>24#include <unity/util/NonCopyable.h>
2425
@@ -31,8 +32,6 @@
31namespace internal32namespace internal
32{33{
3334
34typedef std::function<void(std::string const& message)> SubscriberCallback;
35
36class MWSubscriber35class MWSubscriber
37{36{
38public:37public:
@@ -42,10 +41,12 @@
42 virtual ~MWSubscriber();41 virtual ~MWSubscriber();
4342
44 virtual std::string endpoint() const = 0;43 virtual std::string endpoint() const = 0;
45 virtual void set_message_callback(SubscriberCallback callback) = 0;44 core::Signal<std::string const&> const& message_received() const;
4645
47protected:46protected:
48 MWSubscriber();47 MWSubscriber();
48
49 core::Signal<std::string const&> message_received_;
49};50};
5051
51} // namespace internal52} // namespace internal
5253
=== modified file 'include/unity/scopes/internal/RegistryImpl.h'
--- include/unity/scopes/internal/RegistryImpl.h 2014-05-19 08:28:08 +0000
+++ include/unity/scopes/internal/RegistryImpl.h 2014-06-03 09:42:46 +0000
@@ -43,6 +43,10 @@
43 virtual ScopeMetadata get_metadata(std::string const& scope_id) override;43 virtual ScopeMetadata get_metadata(std::string const& scope_id) override;
44 virtual MetadataMap list() override;44 virtual MetadataMap list() override;
45 virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) override;45 virtual MetadataMap list_if(std::function<bool(ScopeMetadata const& item)> predicate) override;
46 virtual bool is_scope_running(std::string const& scope_id) override;
47
48 virtual core::ScopedConnection set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback) override;
49 virtual core::ScopedConnection set_list_update_callback(std::function<void()> callback) override;
4650
47 // Remote operation. Not part of public API, hence not override.51 // Remote operation. Not part of public API, hence not override.
48 ObjectProxy locate(std::string const& identity);52 ObjectProxy locate(std::string const& identity);
4953
=== modified file 'include/unity/scopes/internal/RegistryObject.h'
--- include/unity/scopes/internal/RegistryObject.h 2014-05-07 04:48:26 +0000
+++ include/unity/scopes/internal/RegistryObject.h 2014-06-03 09:42:46 +0000
@@ -20,6 +20,8 @@
20#define UNITY_SCOPES_INTERNAL_REGISTRYOBJECT_H20#define UNITY_SCOPES_INTERNAL_REGISTRYOBJECT_H
2121
22#include <unity/scopes/internal/Executor.h>22#include <unity/scopes/internal/Executor.h>
23#include <unity/scopes/internal/MiddlewareBase.h>
24#include <unity/scopes/internal/MWPublisher.h>
23#include <unity/scopes/internal/MWRegistryProxyFwd.h>25#include <unity/scopes/internal/MWRegistryProxyFwd.h>
24#include <unity/scopes/internal/RegistryObjectBase.h>26#include <unity/scopes/internal/RegistryObjectBase.h>
25#include <unity/scopes/internal/StateReceiverObject.h>27#include <unity/scopes/internal/StateReceiverObject.h>
@@ -55,13 +57,15 @@
55public:57public:
56 UNITY_DEFINES_PTRS(RegistryObject);58 UNITY_DEFINES_PTRS(RegistryObject);
5759
58 RegistryObject(core::posix::ChildProcess::DeathObserver& death_observer, Executor::SPtr const& executor);60 RegistryObject(core::posix::ChildProcess::DeathObserver& death_observer, Executor::SPtr const& executor,
61 MiddlewareBase::SPtr middleware);
59 virtual ~RegistryObject();62 virtual ~RegistryObject();
6063
61 // Remote operation implementations64 // Remote operation implementations
62 virtual ScopeMetadata get_metadata(std::string const& scope_id) const override;65 virtual ScopeMetadata get_metadata(std::string const& scope_id) const override;
63 virtual MetadataMap list() const override;66 virtual MetadataMap list() const override;
64 virtual ObjectProxy locate(std::string const& identity) override;67 virtual ObjectProxy locate(std::string const& identity) override;
68 virtual bool is_scope_running(std::string const& scope_id) override;
6569
66 // Local methods70 // Local methods
67 bool add_local_scope(std::string const& scope_id, ScopeMetadata const& scope,71 bool add_local_scope(std::string const& scope_id, ScopeMetadata const& scope,
@@ -69,7 +73,6 @@
69 bool remove_local_scope(std::string const& scope_id);73 bool remove_local_scope(std::string const& scope_id);
70 void set_remote_registry(MWRegistryProxy const& remote_registry);74 void set_remote_registry(MWRegistryProxy const& remote_registry);
7175
72 bool is_scope_running(std::string const& scope_id);
73 StateReceiverObject::SPtr state_receiver();76 StateReceiverObject::SPtr state_receiver();
7477
75private:78private:
@@ -84,7 +87,7 @@
84 Stopped, Starting, Running, Stopping87 Stopped, Starting, Running, Stopping
85 };88 };
8689
87 ScopeProcess(ScopeExecData exec_data);90 ScopeProcess(ScopeExecData exec_data, MWPublisher::SPtr publisher);
88 ScopeProcess(ScopeProcess const& other);91 ScopeProcess(ScopeProcess const& other);
89 ~ScopeProcess();92 ~ScopeProcess();
9093
@@ -112,6 +115,7 @@
112 mutable std::mutex process_mutex_;115 mutable std::mutex process_mutex_;
113 mutable std::condition_variable state_change_cond_;116 mutable std::condition_variable state_change_cond_;
114 core::posix::ChildProcess process_ = core::posix::ChildProcess::invalid();117 core::posix::ChildProcess process_ = core::posix::ChildProcess::invalid();
118 MWPublisher::SPtr reg_publisher_;
115 };119 };
116120
117private:121private:
@@ -128,6 +132,8 @@
128 ProcessMap scope_processes_;132 ProcessMap scope_processes_;
129 MWRegistryProxy remote_registry_;133 MWRegistryProxy remote_registry_;
130 mutable std::mutex mutex_;134 mutable std::mutex mutex_;
135
136 MWPublisher::SPtr publisher_;
131};137};
132138
133} // namespace internal139} // namespace internal
134140
=== modified file 'include/unity/scopes/internal/RegistryObjectBase.h'
--- include/unity/scopes/internal/RegistryObjectBase.h 2014-04-03 12:57:25 +0000
+++ include/unity/scopes/internal/RegistryObjectBase.h 2014-06-03 09:42:46 +0000
@@ -39,6 +39,7 @@
39 virtual ScopeMetadata get_metadata(std::string const& scope_id) const = 0;39 virtual ScopeMetadata get_metadata(std::string const& scope_id) const = 0;
40 virtual MetadataMap list() const = 0;40 virtual MetadataMap list() const = 0;
41 virtual ObjectProxy locate(std::string const& identity) = 0;41 virtual ObjectProxy locate(std::string const& identity) = 0;
42 virtual bool is_scope_running(std::string const& scope_id) = 0;
42};43};
4344
44} // namespace internal45} // namespace internal
4546
=== modified file 'include/unity/scopes/internal/smartscopes/SSRegistryObject.h'
--- include/unity/scopes/internal/smartscopes/SSRegistryObject.h 2014-05-09 05:26:39 +0000
+++ include/unity/scopes/internal/smartscopes/SSRegistryObject.h 2014-06-03 09:42:46 +0000
@@ -54,6 +54,7 @@
54 MetadataMap list() const override;54 MetadataMap list() const override;
5555
56 ObjectProxy locate(std::string const& identity) override;56 ObjectProxy locate(std::string const& identity) override;
57 bool is_scope_running(std::string const& scope_id) override;
5758
58 bool has_scope(std::string const& scope_id) const;59 bool has_scope(std::string const& scope_id) const;
59 std::string get_base_url(std::string const& scope_id) const;60 std::string get_base_url(std::string const& scope_id) const;
6061
=== modified file 'include/unity/scopes/internal/zmq_middleware/RegistryI.h'
--- include/unity/scopes/internal/zmq_middleware/RegistryI.h 2014-04-03 12:57:25 +0000
+++ include/unity/scopes/internal/zmq_middleware/RegistryI.h 2014-06-03 09:42:46 +0000
@@ -59,6 +59,10 @@
59 virtual void locate_(Current const& current,59 virtual void locate_(Current const& current,
60 capnp::AnyPointer::Reader& in_params,60 capnp::AnyPointer::Reader& in_params,
61 capnproto::Response::Builder& r);61 capnproto::Response::Builder& r);
62
63 virtual void is_scope_running_(Current const& current,
64 capnp::AnyPointer::Reader& in_params,
65 capnproto::Response::Builder& r);
62};66};
6367
64} // namespace zmq_middleware68} // namespace zmq_middleware
6569
=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-04-03 12:57:25 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqRegistry.h 2014-06-03 09:42:46 +0000
@@ -52,6 +52,7 @@
52 virtual ScopeMetadata get_metadata(std::string const& scope_id) override;52 virtual ScopeMetadata get_metadata(std::string const& scope_id) override;
53 virtual MetadataMap list() override;53 virtual MetadataMap list() override;
54 virtual ObjectProxy locate(std::string const& identity) override;54 virtual ObjectProxy locate(std::string const& identity) override;
55 virtual bool is_scope_running(std::string const& scope_id) override;
55};56};
5657
57} // namespace zmq_middleware58} // namespace zmq_middleware
5859
=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 2014-05-19 09:17:14 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqSubscriber.h 2014-06-03 09:42:46 +0000
@@ -19,13 +19,11 @@
19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H19#ifndef UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H
20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H20#define UNITY_SCOPES_INTERNAL_ZMQMIDDLEWARE_ZMQSUBSCRIBER_H
2121
22#include <condition_variable>
23#include <thread>
22#include <unity/scopes/internal/MWSubscriber.h>24#include <unity/scopes/internal/MWSubscriber.h>
23
24#include <zmqpp/context.hpp>25#include <zmqpp/context.hpp>
2526
26#include <condition_variable>
27#include <thread>
28
29namespace unity27namespace unity
30{28{
3129
@@ -48,7 +46,6 @@
48 virtual ~ZmqSubscriber();46 virtual ~ZmqSubscriber();
4947
50 std::string endpoint() const override;48 std::string endpoint() const override;
51 void set_message_callback(SubscriberCallback callback) override;
5249
53private:50private:
54 enum ThreadState51 enum ThreadState
@@ -56,7 +53,7 @@
56 NotRunning,53 NotRunning,
57 Running,54 Running,
58 Stopping,55 Stopping,
59 Failed56 Stopped
60 };57 };
6158
62 zmqpp::context* const context_;59 zmqpp::context* const context_;
@@ -70,8 +67,6 @@
70 ThreadState thread_state_;67 ThreadState thread_state_;
71 std::exception_ptr thread_exception_;68 std::exception_ptr thread_exception_;
7269
73 SubscriberCallback callback_;
74
75 void subscriber_thread();70 void subscriber_thread();
76};71};
7772
7873
=== modified file 'include/unity/scopes/testing/MockRegistry.h'
--- include/unity/scopes/testing/MockRegistry.h 2014-05-19 08:31:25 +0000
+++ include/unity/scopes/testing/MockRegistry.h 2014-06-03 09:42:46 +0000
@@ -43,6 +43,15 @@
43 MOCK_METHOD1(get_metadata, ScopeMetadata(std::string const&));43 MOCK_METHOD1(get_metadata, ScopeMetadata(std::string const&));
44 MOCK_METHOD0(list, MetadataMap());44 MOCK_METHOD0(list, MetadataMap());
45 MOCK_METHOD1(list_if, MetadataMap(std::function<bool(ScopeMetadata const&)>));45 MOCK_METHOD1(list_if, MetadataMap(std::function<bool(ScopeMetadata const&)>));
46 MOCK_METHOD1(is_scope_running, bool(std::string const&));
47 core::ScopedConnection set_scope_state_callback(std::string const&, std::function<void(bool is_running)>) override
48 {
49 return core::Signal<>().connect([]{});
50 }
51 core::ScopedConnection set_list_update_callback(std::function<void()>) override
52 {
53 return core::Signal<>().connect([]{});
54 }
46};55};
4756
48/// @endcond57/// @endcond
4958
=== modified file 'scoperegistry/CMakeLists.txt'
--- scoperegistry/CMakeLists.txt 2014-05-19 08:40:28 +0000
+++ scoperegistry/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -1,6 +1,8 @@
1set(SRC1set(SRC
2 DirWatcher.cpp
2 FindFiles.cpp3 FindFiles.cpp
3 scoperegistry.cpp4 scoperegistry.cpp
5 ScopesWatcher.cpp
4)6)
57
6include_directories(${CMAKE_CURRENT_SOURCE_DIR})8include_directories(${CMAKE_CURRENT_SOURCE_DIR})
79
=== added file 'scoperegistry/DirWatcher.cpp'
--- scoperegistry/DirWatcher.cpp 1970-01-01 00:00:00 +0000
+++ scoperegistry/DirWatcher.cpp 2014-06-03 09:42:46 +0000
@@ -0,0 +1,272 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include "DirWatcher.h"
20
21#include <unity/UnityExceptions.h>
22
23#include <iostream>
24#include <sys/inotify.h>
25#include <sys/ioctl.h>
26#include <unistd.h>
27
28using namespace unity;
29
30namespace scoperegistry
31{
32
33DirWatcher::DirWatcher()
34 : fd_(inotify_init())
35 , thread_state_(Running)
36 , thread_exception_(nullptr)
37{
38 // Validate the file descriptor
39 if (fd_ < 0)
40 {
41 throw SyscallException("DirWatcher(): inotify_init() failed on inotify fd (fd = " +
42 std::to_string(fd_) + ")", errno);
43 }
44}
45
46DirWatcher::~DirWatcher()
47{
48 {
49 std::lock_guard<std::mutex> lock(mutex_);
50
51 if (thread_state_ == Failed)
52 {
53 try
54 {
55 std::rethrow_exception(thread_exception_);
56 }
57 catch (std::exception const& e)
58 {
59 std::cerr << "~DirWatcher(): " << e.what() << std::endl;
60 }
61 catch (...)
62 {
63 std::cerr << "~DirWatcher(): watch_thread was aborted due to an unknown exception"
64 << std::endl;
65 }
66 }
67 else
68 {
69 // Set state to Stopping
70 thread_state_ = Stopping;
71
72 // Remove watches (causes read to return)
73 for (auto& wd : wds_)
74 {
75 inotify_rm_watch(fd_, wd.first);
76 }
77 wds_.clear();
78 }
79 }
80
81 // Wait for thread to terminate
82 if (thread_.joinable())
83 {
84 thread_.join();
85 }
86
87 // Close the file descriptor
88 close(fd_);
89}
90
91void DirWatcher::add_watch(std::string const& path)
92{
93 std::lock_guard<std::mutex> lock(mutex_);
94
95 if (thread_state_ == Failed)
96 {
97 std::rethrow_exception(thread_exception_);
98 }
99
100 for (auto const& wd : wds_)
101 {
102 if (wd.second == path)
103 {
104 throw ResourceException("DirWatcher::add_watch(): failed to add watch for path: \"" +
105 path + "\". Watch already exists.");
106 }
107 }
108
109 int wd = inotify_add_watch(fd_, path.c_str(), IN_CREATE | IN_MOVED_TO |
110 IN_DELETE | IN_MOVED_FROM |
111 IN_MODIFY | IN_ATTRIB);
112 if (wd < 0)
113 {
114 throw ResourceException("DirWatcher::add_watch(): failed to add watch for path: \"" +
115 path + "\". inotify_add_watch() failed. (fd = " +
116 std::to_string(fd_) + ", path = " + path + ")");
117 }
118
119 wds_[wd] = path;
120
121 // If this is the first watch, start the thread
122 if (wds_.size() == 1)
123 {
124 thread_ = std::thread(&DirWatcher::watch_thread, this);
125 }
126}
127
128void DirWatcher::remove_watch(std::string const& path)
129{
130 std::lock_guard<std::mutex> lock(mutex_);
131
132 if (thread_state_ == Failed)
133 {
134 std::rethrow_exception(thread_exception_);
135 }
136
137 for (auto const& wd : wds_)
138 {
139 if (wd.second == path)
140 {
141 // If this is the last watch, stop the thread
142 if (wds_.size() == 1)
143 {
144 thread_state_ = Stopping;
145 }
146
147 // Remove watch (causes read to return)
148 inotify_rm_watch(fd_, wd.first);
149 wds_.erase(wd.first);
150 break;
151 }
152 }
153}
154
155void DirWatcher::watch_thread()
156{
157 try
158 {
159 fd_set fds;
160 FD_ZERO(&fds);
161 FD_SET(fd_, &fds);
162
163 int bytes_avail = 0;
164 std::string buffer;
165 std::string event_path;
166
167 // Poll for notifications until stop is requested
168 while (true)
169 {
170 // Wait for a payload to arrive
171 int ret = select(fd_ + 1, &fds, nullptr, nullptr, nullptr);
172 if (ret < 0)
173 {
174 throw SyscallException("DirWatcher::watch_thread(): Thread aborted: "
175 "select() failed on inotify fd (fd = " +
176 std::to_string(fd_) + ")", errno);
177 }
178 // Get number of bytes available
179 ret = ioctl(fd_, FIONREAD, &bytes_avail);
180 if (ret < 0)
181 {
182 throw SyscallException("DirWatcher::watch_thread(): Thread aborted: "
183 "ioctl() failed on inotify fd (fd = " +
184 std::to_string(fd_) + ")", errno);
185 }
186 // Read available bytes
187 buffer.resize(bytes_avail);
188 int bytes_read = read(fd_, &buffer[0], buffer.size());
189 if (bytes_read < 0)
190 {
191 throw SyscallException("DirWatcher::watch_thread(): Thread aborted: "
192 "read() failed on inotify fd (fd = " +
193 std::to_string(fd_) + ")", errno);
194 }
195
196 // Process event(s) received
197 int i = 0;
198 while (i < bytes_read)
199 {
200 struct inotify_event* event = (inotify_event*)&buffer[i];
201 {
202 event_path = "";
203 std::lock_guard<std::mutex> lock(mutex_);
204 if (wds_.find(event->wd) != wds_.end())
205 {
206 event_path = wds_.at(event->wd) + "/" + event->name;
207 }
208 }
209
210 if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
211 {
212 if (event->mask & IN_ISDIR)
213 {
214 watch_event(Added, Directory, event_path);
215 }
216 else
217 {
218 watch_event(Added, File, event_path);
219 }
220 }
221 else if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM)
222 {
223 if (event->mask & IN_ISDIR)
224 {
225 watch_event(Removed, Directory, event_path);
226 }
227 else
228 {
229 watch_event(Removed, File, event_path);
230 }
231 }
232 else if (event->mask & IN_MODIFY || event->mask & IN_ATTRIB)
233 {
234 if (event->mask & IN_ISDIR)
235 {
236 watch_event(Modified, Directory, event_path);
237 }
238 else
239 {
240 watch_event(Modified, File, event_path);
241 }
242 }
243 i += sizeof(inotify_event) + event->len;
244 }
245
246 // Break from the loop if we are stopping
247 {
248 std::lock_guard<std::mutex> lock(mutex_);
249 if (thread_state_ == Stopping)
250 {
251 break;
252 }
253 }
254 }
255 }
256 catch (std::exception const& e)
257 {
258 std::cerr << e.what() << std::endl;
259 std::lock_guard<std::mutex> lock(mutex_);
260 thread_state_ = Failed;
261 thread_exception_ = std::current_exception();
262 }
263 catch (...)
264 {
265 std::cerr << "DirWatcher::watch_thread(): Thread aborted: unknown exception" << std::endl;
266 std::lock_guard<std::mutex> lock(mutex_);
267 thread_state_ = Failed;
268 thread_exception_ = std::current_exception();
269 }
270}
271
272} // namespace scoperegistry
0273
=== added file 'scoperegistry/DirWatcher.h'
--- scoperegistry/DirWatcher.h 1970-01-01 00:00:00 +0000
+++ scoperegistry/DirWatcher.h 2014-06-03 09:42:46 +0000
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef SCOPEREGISTRY_DIRWATCHER_H
20#define SCOPEREGISTRY_DIRWATCHER_H
21
22#include <condition_variable>
23#include <map>
24#include <thread>
25
26namespace scoperegistry
27{
28
29// DirWatcher watches directories specified by calls to add_watch() / remove_watch() for changes in
30// the files and folders contained. If a file or folder is added, removed or modified, the pure
31// virtual watch_event() method is executed (this is to be overridden by a child class deriving
32// from DirWatcher)
33
34class DirWatcher
35{
36public:
37 enum EventType
38 {
39 Added,
40 Removed,
41 Modified
42 };
43
44 enum FileType
45 {
46 File,
47 Directory
48 };
49
50 DirWatcher();
51 ~DirWatcher();
52
53 void add_watch(std::string const& path);
54 void remove_watch(std::string const& path);
55
56private:
57 enum ThreadState
58 {
59 Running,
60 Stopping,
61 Failed
62 };
63
64 int const fd_;
65
66 std::map<int, std::string> wds_;
67
68 std::thread thread_;
69 std::mutex mutex_;
70 ThreadState thread_state_;
71 std::exception_ptr thread_exception_;
72
73 void watch_thread();
74 virtual void watch_event(EventType event_type, FileType file_type, std::string const& path) = 0;
75};
76
77} // namespace scoperegistry
78
79#endif // SCOPEREGISTRY_DIRWATCHER_H
080
=== modified file 'scoperegistry/FindFiles.cpp'
--- scoperegistry/FindFiles.cpp 2014-05-21 02:07:16 +0000
+++ scoperegistry/FindFiles.cpp 2014-06-03 09:42:46 +0000
@@ -36,14 +36,9 @@
36namespace scoperegistry36namespace scoperegistry
37{37{
3838
39namespace
40{
41
42// Return all paths underneath the given dir that are of the given type39// Return all paths underneath the given dir that are of the given type
43// or are a symbolic link.40// or are a symbolic link.
4441
45enum EntryType { File, Directory };
46
47vector<string> find_entries(string const& install_dir, EntryType type)42vector<string> find_entries(string const& install_dir, EntryType type)
48{43{
49 DIR* d = opendir(install_dir.c_str());44 DIR* d = opendir(install_dir.c_str());
@@ -83,39 +78,56 @@
83 return entries;78 return entries;
84}79}
8580
86} // namespace81// Return all files of the form dir/<scomescope>.ini that are regular files or
82// symbolic links and have the specified suffix.
83// The empty suffix is legal and causes all regular files and symlinks to be returned.
84
85map<string, string> find_scope_dir_configs(string const& scope_dir, string const& suffix)
86{
87 map<string, string> files;
88
89 auto paths = find_entries(scope_dir, File);
90 for (auto path : paths)
91 {
92 filesystem::path fs_path(path);
93 if (fs_path.extension() != suffix)
94 {
95 continue;
96 }
97 auto scope_id = fs_path.stem().native();
98 files.insert(make_pair(scope_id, path));
99 }
100
101 return files;
102}
87103
88// Return all files of the form dir/*/<scomescope>.ini that are regular files or104// Return all files of the form dir/*/<scomescope>.ini that are regular files or
89// symbolic links and have the specified suffix.105// symbolic links and have the specified suffix.
90// The empty suffix is legal and causes all regular files and symlinks to be returned.106// The empty suffix is legal and causes all regular files and symlinks to be returned.
91// Print error message for any scopes with an id that was seen previously.107// Print error message for any scopes with an id that was seen previously.
92108
93vector<string> find_scope_config_files(string const& install_dir,109map<string, string> find_install_dir_configs(string const& install_dir,
94 string const& suffix,110 string const& suffix,
95 function<void(string const&)> error)111 function<void(string const&)> error)
96{112{
97 vector<string> files;113 map<string, string> files;
98 map<string, string> scopes_seen;114 map<string, string> scopes_seen;
99115
100 auto subdirs = find_entries(install_dir, Directory);116 auto scope_dirs = find_entries(install_dir, Directory);
101 for (auto subdir : subdirs)117 for (auto scope_dir : scope_dirs)
102 {118 {
103 auto candidates = find_entries(subdir, File);119 auto configs = find_scope_dir_configs(scope_dir, suffix);
104 for (auto c : candidates)120 for (auto config : configs)
105 {121 {
106 filesystem::path path(c);122 auto const it = scopes_seen.find(config.first);
107 if (path.extension() != suffix) {
108 continue;
109 }
110 auto stem = path.stem().native();
111 auto const it = scopes_seen.find(stem);
112 if (it != scopes_seen.end())123 if (it != scopes_seen.end())
113 {124 {
114 error("ignoring second instance of non-unique scope: " + path.native() + "\n"125 error("ignoring second instance of non-unique scope: " + config.second + "\n"
115 "previous instance: " + it->second);126 "previous instance: " + it->second);
127 continue;
116 }128 }
117 scopes_seen[stem] = path.native();129 scopes_seen[config.first] = config.second;
118 files.emplace_back(c);130 files.insert(config);
119 }131 }
120 }132 }
121133
122134
=== modified file 'scoperegistry/FindFiles.h'
--- scoperegistry/FindFiles.h 2014-05-21 02:07:16 +0000
+++ scoperegistry/FindFiles.h 2014-06-03 09:42:46 +0000
@@ -21,12 +21,25 @@
2121
22#include <functional>22#include <functional>
23#include <string>23#include <string>
24#include <map>
24#include <vector>25#include <vector>
2526
26namespace scoperegistry27namespace scoperegistry
27{28{
2829
29// Return a vector of file names underneath a scope root install dir that have the given suffix.30// Return a vector of all paths found underneath a given dir that are of the given type or are
31// a symbolic link.
32
33enum EntryType { File, Directory };
34std::vector<std::string> find_entries(std::string const& install_dir, EntryType type);
35
36// Return a map of file names:paths underneath a scope dir that have the given suffix. Files are
37// searched for in the specified directory only, that is, no .ini files in further-nested
38// directories will be searched.
39
40std::map<std::string, std::string> find_scope_dir_configs(std::string const& scope_dir, std::string const& suffix);
41
42// Return a map of file names:paths underneath a scope root install dir that have the given suffix.
30// Files are searched for exactly "one level down", that is, if we have a directory structure.43// Files are searched for exactly "one level down", that is, if we have a directory structure.
31//44//
32// canonical/scopeA/myconfig.ini45// canonical/scopeA/myconfig.ini
@@ -35,14 +48,9 @@
35// we get those two .ini files, but no .ini files in canonical or underneath48// we get those two .ini files, but no .ini files in canonical or underneath
36// further-nested directories.49// further-nested directories.
3750
38std::vector<std::string> find_scope_config_files(std::string const& install_dir,51std::map<std::string, std::string> find_install_dir_configs(std::string const& install_dir,
39 std::string const& suffix,52 std::string const& suffix,
40 std::function<void(std::string const&)> error);53 std::function<void(std::string const&)> error);
41
42// Return a vector of file names in dir with the given suffix.
43
44std::vector<std::string> find_files(std::string const& dir,
45 std::string const& suffix);
4654
47} // namespace scoperegistry55} // namespace scoperegistry
4856
4957
=== added file 'scoperegistry/ScopesWatcher.cpp'
--- scoperegistry/ScopesWatcher.cpp 1970-01-01 00:00:00 +0000
+++ scoperegistry/ScopesWatcher.cpp 2014-06-03 09:42:46 +0000
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#include "ScopesWatcher.h"
20
21#include "FindFiles.h"
22
23#include <boost/filesystem/path.hpp>
24
25using namespace unity::scopes::internal;
26using namespace boost;
27
28namespace scoperegistry
29{
30
31ScopesWatcher::ScopesWatcher(RegistryObject::SPtr registry,
32 std::function<void(std::pair<std::string, std::string> const&)> ini_added_callback)
33 : registry_(registry)
34 , ini_added_callback_(ini_added_callback)
35{
36}
37
38void ScopesWatcher::add_install_dir(std::string const& dir)
39{
40 try
41 {
42 // Add watch for root directory
43 add_watch(dir);
44
45 // Add watches for each sub directory in root
46 auto subdirs = find_entries(dir, EntryType::Directory);
47 for (auto const& subdir : subdirs)
48 {
49 auto configs = find_scope_dir_configs(subdir, ".ini");
50 if (!configs.empty())
51 {
52 auto config = *configs.cbegin();
53 std::lock_guard<std::mutex> lock(mutex_);
54 dir_to_ini_map_[subdir] = config.second;
55 }
56 add_watch(subdir);
57 }
58 }
59 catch (...) {}
60}
61
62void ScopesWatcher::add_scope_dir(std::string const& dir)
63{
64 auto configs = find_scope_dir_configs(dir, ".ini");
65 if (!configs.empty())
66 {
67 auto config = *configs.cbegin();
68 // Associate this directory with the contained config file
69 {
70 std::lock_guard<std::mutex> lock(mutex_);
71 dir_to_ini_map_[dir] = config.second;
72 }
73
74 // New config found, execute callback
75 ini_added_callback_(config);
76 std::cout << "ScopesWatcher: scope: \"" << config.first << "\" installed to: \""
77 << dir << "\"" << std::endl;
78 }
79
80 // Add a watch for this directory
81 add_watch(dir);
82}
83
84void ScopesWatcher::remove_scope_dir(std::string const& dir)
85{
86 std::lock_guard<std::mutex> lock(mutex_);
87
88 // Check if this directory is associate with the config file
89 if (dir_to_ini_map_.find(dir) != dir_to_ini_map_.end())
90 {
91 // Inform the registry that this scope has been removed
92 std::string ini_path = dir_to_ini_map_.at(dir);
93 dir_to_ini_map_.erase(dir);
94
95 filesystem::path p(ini_path);
96 std::string scope_id = p.stem().native();
97 registry_->remove_local_scope(scope_id);
98 std::cout << "ScopesWatcher: scope: \"" << scope_id << "\" uninstalled from: \""
99 << dir << "\"" << std::endl;
100 }
101
102 // Remove the watch for this directory
103 remove_watch(dir);
104}
105
106void ScopesWatcher::watch_event(DirWatcher::EventType event_type,
107 DirWatcher::FileType file_type,
108 std::string const& path)
109{
110 filesystem::path fs_path(path);
111
112 if (file_type == DirWatcher::File && fs_path.extension() == ".ini")
113 {
114 std::lock_guard<std::mutex> lock(mutex_);
115 std::string parent_path = fs_path.parent_path().native();
116 std::string scope_id = fs_path.stem().native();
117
118 // A .ini has been added / modified
119 if (event_type == DirWatcher::Added || event_type == DirWatcher::Modified)
120 {
121 dir_to_ini_map_[parent_path] = path;
122 ini_added_callback_(std::make_pair(scope_id, path));
123 std::cout << "ScopesWatcher: scope: \"" << scope_id << "\" installed to: \""
124 << parent_path << "\"" << std::endl;
125 }
126 // A .ini has been removed
127 else if (event_type == DirWatcher::Removed)
128 {
129 dir_to_ini_map_.erase(parent_path);
130 registry_->remove_local_scope(scope_id);
131 std::cout << "ScopesWatcher: scope: \"" << scope_id << "\" uninstalled from: \""
132 << parent_path << "\"" << std::endl;
133 }
134 }
135 else if (file_type == DirWatcher::File && fs_path.extension() == ".so")
136 {
137 std::lock_guard<std::mutex> lock(mutex_);
138 std::string parent_path = fs_path.parent_path().native();
139
140 // Check if this directory is associate with the config file
141 if (dir_to_ini_map_.find(parent_path) != dir_to_ini_map_.end())
142 {
143 std::string ini_path = dir_to_ini_map_.at(parent_path);
144 filesystem::path fs_ini_path(ini_path);
145 std::string scope_id = fs_ini_path.stem().native();
146
147 // A .so file has been added / modified
148 if (event_type == DirWatcher::Added || event_type == DirWatcher::Modified)
149 {
150 ini_added_callback_(std::make_pair(scope_id, ini_path));
151 std::cout << "ScopesWatcher: scope: \"" << scope_id << "\" installed to: \""
152 << parent_path << "\"" << std::endl;
153 }
154 // A .so file has been removed
155 else if (event_type == DirWatcher::Removed)
156 {
157 registry_->remove_local_scope(scope_id);
158 std::cout << "ScopesWatcher: scope: \"" << scope_id << "\" uninstalled from: \""
159 << parent_path << "\"" << std::endl;
160 }
161 }
162 }
163 else
164 {
165 // A new sub directory has been added
166 if (event_type == DirWatcher::Added)
167 {
168 // try add this path as a scope folder
169 // (we need to do this with both files and folders added, as the file added may be a symlink)
170 try
171 {
172 add_scope_dir(path);
173 }
174 catch (...) {}
175 }
176 // A sub directory has been removed
177 else if (event_type == DirWatcher::Removed)
178 {
179 remove_scope_dir(path);
180 }
181 }
182}
183
184} // namespace scoperegistry
0185
=== added file 'scoperegistry/ScopesWatcher.h'
--- scoperegistry/ScopesWatcher.h 1970-01-01 00:00:00 +0000
+++ scoperegistry/ScopesWatcher.h 2014-06-03 09:42:46 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 */
18
19#ifndef SCOPEREGISTRY_SCOPESWATCHER_H
20#define SCOPEREGISTRY_SCOPESWATCHER_H
21
22#include <DirWatcher.h>
23
24#include <unity/scopes/internal/RegistryObject.h>
25
26namespace scoperegistry
27{
28
29// ScopesWatcher watches the scope install directories specified by calls to add_install_dir() for
30// the installation / uninstallation of scopes. If a scope is removed, the registry is informed
31// accordingly. If a scope is added, a user callback (provided on construction) is executed.
32
33class ScopesWatcher : public DirWatcher
34{
35public:
36 ScopesWatcher(unity::scopes::internal::RegistryObject::SPtr registry,
37 std::function<void(std::pair<std::string, std::string> const&)> ini_added_callback);
38
39 void add_install_dir(std::string const& dir);
40
41private:
42 unity::scopes::internal::RegistryObject::SPtr const registry_;
43 std::function<void(std::pair<std::string, std::string> const&)> const ini_added_callback_;
44 std::map<std::string, std::string> dir_to_ini_map_;
45 std::mutex mutex_;
46
47 void add_scope_dir(std::string const& dir);
48 void remove_scope_dir(std::string const& dir);
49
50 void watch_event(DirWatcher::EventType event_type,
51 DirWatcher::FileType file_type,
52 std::string const& path) override;
53};
54
55} // namespace scoperegistry
56
57#endif // SCOPEREGISTRY_SCOPESWATCHER_H
058
=== modified file 'scoperegistry/scoperegistry.cpp'
--- scoperegistry/scoperegistry.cpp 2014-05-21 02:07:16 +0000
+++ scoperegistry/scoperegistry.cpp 2014-06-03 09:42:46 +0000
@@ -17,6 +17,7 @@
17 */17 */
1818
19#include "FindFiles.h"19#include "FindFiles.h"
20#include "ScopesWatcher.h"
2021
21#include <unity/scopes/internal/MiddlewareFactory.h>22#include <unity/scopes/internal/MiddlewareFactory.h>
22#include <unity/scopes/internal/MWRegistry.h>23#include <unity/scopes/internal/MWRegistry.h>
@@ -136,26 +137,24 @@
136 map<string, string> fixed_scopes; // Scopes that the OEM cannot override137 map<string, string> fixed_scopes; // Scopes that the OEM cannot override
137 map<string, string> overrideable_scopes; // Scopes that the OEM can override138 map<string, string> overrideable_scopes; // Scopes that the OEM can override
138139
139 auto config_files = find_scope_config_files(scope_installdir, ".ini", error);140 auto config_files = find_install_dir_configs(scope_installdir, ".ini", error);
140 for (auto&& path : config_files)141 for (auto&& path : config_files)
141 {142 {
142 filesystem::path p(path);
143 string scope_id = p.stem().native();
144 try143 try
145 {144 {
146 ScopeConfig config(path);145 ScopeConfig config(path.second);
147 if (config.overrideable())146 if (config.overrideable())
148 {147 {
149 overrideable_scopes[scope_id] = path;148 overrideable_scopes[path.first] = path.second;
150 }149 }
151 else150 else
152 {151 {
153 fixed_scopes[scope_id] = path;152 fixed_scopes[path.first] = path.second;
154 }153 }
155 }154 }
156 catch (unity::Exception const& e)155 catch (unity::Exception const& e)
157 {156 {
158 error("ignoring scope \"" + scope_id + "\": configuration error:\n" + e.what());157 error("ignoring scope \"" + path.first + "\": configuration error:\n" + e.what());
159 }158 }
160 }159 }
161160
@@ -163,19 +162,16 @@
163 {162 {
164 try163 try
165 {164 {
166 auto oem_paths = find_scope_config_files(oem_installdir, ".ini", error);165 auto oem_paths = find_install_dir_configs(oem_installdir, ".ini", error);
167 for (auto&& path : oem_paths)166 for (auto&& path : oem_paths)
168 {167 {
169 filesystem::path p(path);168 if (fixed_scopes.find(path.first) == fixed_scopes.end())
170 string file_name = p.filename().native();
171 string scope_id = p.stem().native();
172 if (fixed_scopes.find(scope_id) == fixed_scopes.end())
173 {169 {
174 overrideable_scopes[scope_id] = path; // Replaces scope if it was present already170 overrideable_scopes[path.first] = path.second; // Replaces scope if it was present already
175 }171 }
176 else172 else
177 {173 {
178 error("ignoring non-overrideable scope config \"" + file_name + "\" in OEM directory " + oem_installdir);174 error("ignoring non-overrideable scope config \"" + path.second + "\" in OEM directory " + oem_installdir);
179 }175 }
180 }176 }
181 }177 }
@@ -199,19 +195,16 @@
199 {195 {
200 try196 try
201 {197 {
202 auto click_paths = find_scope_config_files(click_installdir, ".ini", error);198 auto click_paths = find_install_dir_configs(click_installdir, ".ini", error);
203 for (auto&& path : click_paths)199 for (auto&& path : click_paths)
204 {200 {
205 filesystem::path p(path);201 if (local_scopes.find(path.first) == local_scopes.end())
206 string file_name = p.filename().native();
207 string scope_id = p.stem().native();
208 if (local_scopes.find(scope_id) == local_scopes.end())
209 {202 {
210 click_scopes[scope_id] = path;203 click_scopes[path.first] = path.second;
211 }204 }
212 else205 else
213 {206 {
214 error("ignoring non-overrideable scope config \"" + file_name + "\" in click directory " + click_installdir);207 error("ignoring non-overrideable scope config \"" + path.second + "\" in click directory " + click_installdir);
215 }208 }
216 }209 }
217 }210 }
@@ -228,6 +221,94 @@
228// For each scope, open the config file for the scope, create the metadata info from the config,221// For each scope, open the config file for the scope, create the metadata info from the config,
229// and add an entry to the RegistryObject.222// and add an entry to the RegistryObject.
230223
224void add_local_scope(RegistryObject::SPtr const& registry,
225 pair<string, string> const& scope,
226 MiddlewareBase::SPtr const& mw,
227 string const& scoperunner_path,
228 string const& config_file,
229 bool click,
230 int timeout_ms)
231{
232 unique_ptr<ScopeMetadataImpl> mi(new ScopeMetadataImpl(mw.get()));
233 string scope_config(scope.second);
234 ScopeConfig sc(scope_config);
235
236 filesystem::path scope_path(scope_config);
237 filesystem::path scope_dir(scope_path.parent_path());
238
239 mi->set_scope_id(scope.first);
240 mi->set_display_name(sc.display_name());
241 mi->set_description(sc.description());
242 mi->set_author(sc.author());
243 mi->set_invisible(sc.invisible());
244 mi->set_appearance_attributes(sc.appearance_attributes());
245 mi->set_scope_directory(scope_dir.native());
246 mi->set_results_ttl_type(sc.results_ttl_type());
247
248 try
249 {
250 mi->set_art(relative_scope_path_to_abs_path(sc.art(), scope_dir).native());
251 }
252 catch (NotFoundException const&)
253 {
254 }
255 try
256 {
257 mi->set_icon(relative_scope_path_to_abs_path(sc.icon(), scope_dir).native());
258 }
259 catch (NotFoundException const&)
260 {
261 }
262 try
263 {
264 mi->set_search_hint(sc.search_hint());
265 }
266 catch (NotFoundException const&)
267 {
268 }
269 try
270 {
271 mi->set_hot_key(sc.hot_key());
272 }
273 catch (NotFoundException const&)
274 {
275 }
276
277 ScopeProxy proxy = ScopeImpl::create(mw->create_scope_proxy(scope.first), mw->runtime(), scope.first);
278 mi->set_proxy(proxy);
279 auto meta = ScopeMetadataImpl::create(move(mi));
280
281 RegistryObject::ScopeExecData exec_data;
282 exec_data.scope_id = scope.first;
283 // get custom scope runner executable, if not set use default scoperunner
284 exec_data.scoperunner_path = scoperunner_path;
285
286 if (click)
287 {
288 exec_data.confinement_profile =
289 scope_path.parent_path().filename().native();
290 }
291
292 exec_data.timeout_ms = timeout_ms;
293
294 try
295 {
296 auto custom_exec = sc.scope_runner();
297 if (custom_exec.empty())
298 {
299 throw unity::InvalidArgumentException("Invalid scope runner executable for scope: " + scope.first);
300 }
301 exec_data.scoperunner_path = relative_scope_path_to_abs_path(custom_exec, scope_dir).native();
302 }
303 catch (NotFoundException const&)
304 {
305 }
306 exec_data.runtime_config = config_file;
307 exec_data.scope_config = scope.second;
308
309 registry->add_local_scope(scope.first, move(meta), exec_data);
310}
311
231void add_local_scopes(RegistryObject::SPtr const& registry,312void add_local_scopes(RegistryObject::SPtr const& registry,
232 map<string, string> const& all_scopes,313 map<string, string> const& all_scopes,
233 MiddlewareBase::SPtr const& mw,314 MiddlewareBase::SPtr const& mw,
@@ -240,84 +321,7 @@
240 {321 {
241 try322 try
242 {323 {
243 unique_ptr<ScopeMetadataImpl> mi(new ScopeMetadataImpl(mw.get()));324 add_local_scope(registry, pair, mw, scoperunner_path, config_file, click, timeout_ms);
244 string scope_config(pair.second);
245 ScopeConfig sc(scope_config);
246
247 filesystem::path scope_path(scope_config);
248 filesystem::path scope_dir(scope_path.parent_path());
249
250 mi->set_scope_id(pair.first);
251 mi->set_display_name(sc.display_name());
252 mi->set_description(sc.description());
253 mi->set_author(sc.author());
254 mi->set_invisible(sc.invisible());
255 mi->set_appearance_attributes(sc.appearance_attributes());
256 mi->set_scope_directory(scope_dir.native());
257 mi->set_results_ttl_type(sc.results_ttl_type());
258
259 try
260 {
261 mi->set_art(relative_scope_path_to_abs_path(sc.art(), scope_dir).native());
262 }
263 catch (NotFoundException const&)
264 {
265 }
266 try
267 {
268 mi->set_icon(relative_scope_path_to_abs_path(sc.icon(), scope_dir).native());
269 }
270 catch (NotFoundException const&)
271 {
272 }
273 try
274 {
275 mi->set_search_hint(sc.search_hint());
276 }
277 catch (NotFoundException const&)
278 {
279 }
280 try
281 {
282 mi->set_hot_key(sc.hot_key());
283 }
284 catch (NotFoundException const&)
285 {
286 }
287
288 ScopeProxy proxy = ScopeImpl::create(mw->create_scope_proxy(pair.first), mw->runtime(), pair.first);
289 mi->set_proxy(proxy);
290 auto meta = ScopeMetadataImpl::create(move(mi));
291
292 RegistryObject::ScopeExecData exec_data;
293 exec_data.scope_id = pair.first;
294 // get custom scope runner executable, if not set use default scoperunner
295 exec_data.scoperunner_path = scoperunner_path;
296
297 if (click)
298 {
299 exec_data.confinement_profile =
300 scope_path.parent_path().filename().native();
301 }
302
303 exec_data.timeout_ms = timeout_ms;
304
305 try
306 {
307 auto custom_exec = sc.scope_runner();
308 if (custom_exec.empty())
309 {
310 throw unity::InvalidArgumentException("Invalid scope runner executable for scope: " + pair.first);
311 }
312 exec_data.scoperunner_path = relative_scope_path_to_abs_path(custom_exec, scope_dir).native();
313 }
314 catch (NotFoundException const&)
315 {
316 }
317 exec_data.runtime_config = config_file;
318 exec_data.scope_config = pair.second;
319
320 registry->add_local_scope(pair.first, move(meta), exec_data);
321 }325 }
322 catch (unity::Exception const& e)326 catch (unity::Exception const& e)
323 {327 {
@@ -403,7 +407,7 @@
403407
404 // The registry object stores the local and remote scopes408 // The registry object stores the local and remote scopes
405 Executor::SPtr executor = make_shared<Executor>();409 Executor::SPtr executor = make_shared<Executor>();
406 RegistryObject::SPtr registry(new RegistryObject(*signal_handler_wrapper.death_observer, executor));410 RegistryObject::SPtr registry(new RegistryObject(*signal_handler_wrapper.death_observer, executor, middleware));
407411
408 // Add the metadata for each scope to the lookup table.412 // Add the metadata for each scope to the lookup table.
409 // We do this before starting any of the scopes, so aggregating scopes don't get a lookup failure if413 // We do this before starting any of the scopes, so aggregating scopes don't get a lookup failure if
@@ -433,6 +437,38 @@
433 registry->set_remote_registry(middleware->ss_registry_proxy());437 registry->set_remote_registry(middleware->ss_registry_proxy());
434 }438 }
435439
440 // Configure watches for scope install directories
441 ScopesWatcher local_scopes_watcher(registry,
442 [registry, &middleware, &scoperunner_path, &config_file, process_timeout]
443 (pair<string, string> const& scope)
444 {
445 try
446 {
447 add_local_scope(registry, scope, middleware, scoperunner_path, config_file, false, process_timeout);
448 }
449 catch (unity::Exception const& e)
450 {
451 error("ignoring installed scope \"" + scope.first + "\": cannot create metadata: " + e.what());
452 }
453 });
454 local_scopes_watcher.add_install_dir(scope_installdir);
455 local_scopes_watcher.add_install_dir(oem_installdir);
456
457 ScopesWatcher click_scopes_watcher(registry,
458 [registry, &middleware, &scoperunner_path, &config_file, process_timeout]
459 (pair<string, string> const& scope)
460 {
461 try
462 {
463 add_local_scope(registry, scope, middleware, scoperunner_path, config_file, true, process_timeout);
464 }
465 catch (unity::Exception const& e)
466 {
467 error("ignoring installed scope \"" + scope.first + "\": cannot create metadata: " + e.what());
468 }
469 });
470 click_scopes_watcher.add_install_dir(click_installdir);
471
436 // Let's add the registry's state receiver to the middleware so that scopes can inform472 // Let's add the registry's state receiver to the middleware so that scopes can inform
437 // the registry of state changes.473 // the registry of state changes.
438 middleware->add_state_receiver_object("StateReceiver", registry->state_receiver());474 middleware->add_state_receiver_object("StateReceiver", registry->state_receiver());
439475
=== modified file 'src/scopes/internal/MWRegistry.cpp'
--- src/scopes/internal/MWRegistry.cpp 2014-01-23 11:28:34 +0000
+++ src/scopes/internal/MWRegistry.cpp 2014-06-03 09:42:46 +0000
@@ -16,7 +16,9 @@
16 * Authored by: Michi Henning <michi.henning@canonical.com>16 * Authored by: Michi Henning <michi.henning@canonical.com>
17 */17 */
1818
19#include <unity/scopes/internal/MiddlewareBase.h>
19#include <unity/scopes/internal/MWRegistry.h>20#include <unity/scopes/internal/MWRegistry.h>
21#include <unity/scopes/internal/RuntimeImpl.h>
2022
21using namespace std;23using namespace std;
2224
@@ -30,7 +32,8 @@
30{32{
3133
32MWRegistry::MWRegistry(MiddlewareBase* mw_base) :34MWRegistry::MWRegistry(MiddlewareBase* mw_base) :
33 MWObjectProxy(mw_base)35 MWObjectProxy(mw_base),
36 mw_base_(mw_base)
34{37{
35}38}
3639
@@ -38,6 +41,25 @@
38{41{
39}42}
4043
44core::ScopedConnection MWRegistry::set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback)
45{
46 if (scope_state_subscribers_.find(scope_id) == scope_state_subscribers_.end())
47 {
48 scope_state_subscribers_[scope_id] = mw_base_->create_subscriber(mw_base_->runtime()->registry_identity(), scope_id);
49 }
50 return scope_state_subscribers_.at(scope_id)->message_received().connect([callback](string const& state){ callback(state == "started"); });
51}
52
53core::ScopedConnection MWRegistry::set_list_update_callback(std::function<void()> callback)
54{
55 if (!list_update_subscriber_)
56 {
57 // Use lazy initialization here to only subscribe to the publisher if a callback is set
58 list_update_subscriber_ = mw_base_->create_subscriber(mw_base_->runtime()->registry_identity());
59 }
60 return list_update_subscriber_->message_received().connect([callback](string const&){ callback(); });
61}
62
41} // namespace internal63} // namespace internal
4264
43} // namespace scopes65} // namespace scopes
4466
=== modified file 'src/scopes/internal/MWSubscriber.cpp'
--- src/scopes/internal/MWSubscriber.cpp 2014-05-14 12:57:34 +0000
+++ src/scopes/internal/MWSubscriber.cpp 2014-06-03 09:42:46 +0000
@@ -35,6 +35,11 @@
35{35{
36}36}
3737
38core::Signal<std::string const&> const& MWSubscriber::message_received() const
39{
40 return message_received_;
41}
42
38} // namespace internal43} // namespace internal
3944
40} // namespace scopes45} // namespace scopes
4146
=== modified file 'src/scopes/internal/RegistryImpl.cpp'
--- src/scopes/internal/RegistryImpl.cpp 2014-05-19 08:28:08 +0000
+++ src/scopes/internal/RegistryImpl.cpp 2014-06-03 09:42:46 +0000
@@ -71,6 +71,21 @@
71 return matching_entries;71 return matching_entries;
72}72}
7373
74bool RegistryImpl::is_scope_running(std::string const& scope_id)
75{
76 return fwd()->is_scope_running(scope_id);
77}
78
79core::ScopedConnection RegistryImpl::set_scope_state_callback(std::string const& scope_id, std::function<void(bool)> callback)
80{
81 return fwd()->set_scope_state_callback(scope_id, callback);
82}
83
84core::ScopedConnection RegistryImpl::set_list_update_callback(std::function<void()> callback)
85{
86 return fwd()->set_list_update_callback(callback);
87}
88
74MWRegistryProxy RegistryImpl::fwd()89MWRegistryProxy RegistryImpl::fwd()
75{90{
76 return dynamic_pointer_cast<MWRegistry>(proxy());91 return dynamic_pointer_cast<MWRegistry>(proxy());
7792
=== modified file 'src/scopes/internal/RegistryObject.cpp'
--- src/scopes/internal/RegistryObject.cpp 2014-05-22 08:45:05 +0000
+++ src/scopes/internal/RegistryObject.cpp 2014-06-03 09:42:46 +0000
@@ -19,6 +19,7 @@
19#include <unity/scopes/internal/RegistryObject.h>19#include <unity/scopes/internal/RegistryObject.h>
2020
21#include <unity/scopes/internal/MWRegistry.h>21#include <unity/scopes/internal/MWRegistry.h>
22#include <unity/scopes/internal/RuntimeImpl.h>
22#include <unity/scopes/ScopeExceptions.h>23#include <unity/scopes/ScopeExceptions.h>
23#include <unity/UnityExceptions.h>24#include <unity/UnityExceptions.h>
2425
@@ -38,7 +39,8 @@
38namespace internal39namespace internal
39{40{
4041
41RegistryObject::RegistryObject(core::posix::ChildProcess::DeathObserver& death_observer, Executor::SPtr const& executor)42RegistryObject::RegistryObject(core::posix::ChildProcess::DeathObserver& death_observer, Executor::SPtr const& executor,
43 MiddlewareBase::SPtr middleware)
42 : death_observer_(death_observer),44 : death_observer_(death_observer),
43 death_observer_connection_45 death_observer_connection_
44 {46 {
@@ -58,6 +60,17 @@
58 },60 },
59 executor_(executor)61 executor_(executor)
60{62{
63 if (middleware)
64 {
65 try
66 {
67 publisher_ = middleware->create_publisher(middleware->runtime()->registry_identity());
68 }
69 catch (std::exception const& e)
70 {
71 std::cerr << "RegistryObject(): failed to create registry publisher: " << e.what() << endl;
72 }
73 }
61}74}
6275
63RegistryObject::~RegistryObject()76RegistryObject::~RegistryObject()
@@ -186,6 +199,19 @@
186 return proxy;199 return proxy;
187}200}
188201
202bool RegistryObject::is_scope_running(std::string const& scope_id)
203{
204 lock_guard<decltype(mutex_)> lock(mutex_);
205
206 auto it = scope_processes_.find(scope_id);
207 if (it != scope_processes_.end())
208 {
209 return it->second.state() != ScopeProcess::ProcessState::Stopped;
210 }
211
212 throw NotFoundException("RegistryObject::is_scope_process_running(): no such scope: ", scope_id);
213}
214
189bool RegistryObject::add_local_scope(std::string const& scope_id, ScopeMetadata const& metadata,215bool RegistryObject::add_local_scope(std::string const& scope_id, ScopeMetadata const& metadata,
190 ScopeExecData const& exec_data)216 ScopeExecData const& exec_data)
191{217{
@@ -208,7 +234,13 @@
208 return_value = false;234 return_value = false;
209 }235 }
210 scopes_.insert(make_pair(scope_id, metadata));236 scopes_.insert(make_pair(scope_id, metadata));
211 scope_processes_.insert(make_pair(scope_id, ScopeProcess(exec_data)));237 scope_processes_.insert(make_pair(scope_id, ScopeProcess(exec_data, publisher_)));
238
239 if (publisher_)
240 {
241 // Send a blank message to subscribers to inform them that the registry has been updated
242 publisher_->send_message("");
243 }
212 return return_value;244 return return_value;
213}245}
214246
@@ -224,7 +256,18 @@
224 lock_guard<decltype(mutex_)> lock(mutex_);256 lock_guard<decltype(mutex_)> lock(mutex_);
225257
226 scope_processes_.erase(scope_id);258 scope_processes_.erase(scope_id);
227 return scopes_.erase(scope_id) == 1;259
260 if (scopes_.erase(scope_id) == 1)
261 {
262 if (publisher_)
263 {
264 // Send a blank message to subscribers to inform them that the registry has been updated
265 publisher_->send_message("");
266 }
267 return true;
268 }
269
270 return false;
228}271}
229272
230void RegistryObject::set_remote_registry(MWRegistryProxy const& remote_registry)273void RegistryObject::set_remote_registry(MWRegistryProxy const& remote_registry)
@@ -233,19 +276,6 @@
233 remote_registry_ = remote_registry;276 remote_registry_ = remote_registry;
234}277}
235278
236bool RegistryObject::is_scope_running(std::string const& scope_id)
237{
238 lock_guard<decltype(mutex_)> lock(mutex_);
239
240 auto it = scope_processes_.find(scope_id);
241 if (it != scope_processes_.end())
242 {
243 return it->second.state() != ScopeProcess::ProcessState::Stopped;
244 }
245
246 throw NotFoundException("RegistryObject::is_scope_process_running(): no such scope: ", scope_id);
247}
248
249StateReceiverObject::SPtr RegistryObject::state_receiver()279StateReceiverObject::SPtr RegistryObject::state_receiver()
250{280{
251 return state_receiver_;281 return state_receiver_;
@@ -286,13 +316,15 @@
286 // simply ignore states from scopes the registry does not know about316 // simply ignore states from scopes the registry does not know about
287}317}
288318
289RegistryObject::ScopeProcess::ScopeProcess(ScopeExecData exec_data)319RegistryObject::ScopeProcess::ScopeProcess(ScopeExecData exec_data, MWPublisher::SPtr publisher)
290 : exec_data_(exec_data)320 : exec_data_(exec_data)
321 , reg_publisher_(publisher)
291{322{
292}323}
293324
294RegistryObject::ScopeProcess::ScopeProcess(ScopeProcess const& other)325RegistryObject::ScopeProcess::ScopeProcess(ScopeProcess const& other)
295 : exec_data_(other.exec_data_)326 : exec_data_(other.exec_data_)
327 , reg_publisher_(other.reg_publisher_)
296{328{
297}329}
298330
@@ -438,10 +470,50 @@
438 {470 {
439 return;471 return;
440 }472 }
441 else if (state == Stopped && state_ != Stopping )473 else if (state == Running)
442 {474 {
443 cerr << "RegistryObject::ScopeProcess: Scope: \"" << exec_data_.scope_id475 if (reg_publisher_)
444 << "\" closed unexpectedly. Either the process crashed or was killed forcefully." << endl;476 {
477 // Send a "started" message to subscribers to inform them that this scope (topic) has started
478 reg_publisher_->send_message("started", exec_data_.scope_id);
479 }
480
481 if (state_ != Starting)
482 {
483 cout << "RegistryObject::ScopeProcess: Process for scope: \"" << exec_data_.scope_id
484 << "\" started manually" << endl;
485
486 // Don't update state, treat this scope as not running if a locate() is requested
487 return;
488 }
489 }
490 else if (state == Stopped)
491 {
492 if (reg_publisher_)
493 {
494 // Send a "stopped" message to subscribers to inform them that this scope (topic) has stopped
495 reg_publisher_->send_message("stopped", exec_data_.scope_id);
496 }
497
498 if (state_ != Stopping)
499 {
500 cerr << "RegistryObject::ScopeProcess: Scope: \"" << exec_data_.scope_id
501 << "\" closed unexpectedly. Either the process crashed or was killed forcefully." << endl;
502 }
503 }
504 else if (state == Stopping && state_ != Running)
505 {
506 if (reg_publisher_)
507 {
508 // Send a "stopped" message to subscribers to inform them that this scope (topic) has stopped
509 reg_publisher_->send_message("stopped", exec_data_.scope_id);
510 }
511
512 cout << "RegistryObject::ScopeProcess: Manually started process for scope: \""
513 << exec_data_.scope_id << "\" terminated" << endl;
514
515 // Don't update state, treat this scope as not running if a locate() is requested
516 return;
445 }517 }
446 state_ = state;518 state_ = state;
447 state_change_cond_.notify_all();519 state_change_cond_.notify_all();
448520
=== modified file 'src/scopes/internal/smartscopes/SSRegistryObject.cpp'
--- src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-05-16 14:29:11 +0000
+++ src/scopes/internal/smartscopes/SSRegistryObject.cpp 2014-06-03 09:42:46 +0000
@@ -127,6 +127,11 @@
127 throw internal::RegistryException("SSRegistryObject::locate(): operation not available");127 throw internal::RegistryException("SSRegistryObject::locate(): operation not available");
128}128}
129129
130bool SSRegistryObject::is_scope_running(std::string const&)
131{
132 throw internal::RegistryException("SSRegistryObject::is_scope_running(): operation not available");
133}
134
130bool SSRegistryObject::has_scope(std::string const& scope_id) const135bool SSRegistryObject::has_scope(std::string const& scope_id) const
131{136{
132 std::lock_guard<std::mutex> lock(scopes_mutex_);137 std::lock_guard<std::mutex> lock(scopes_mutex_);
133138
=== modified file 'src/scopes/internal/zmq_middleware/ObjectAdapter.cpp'
--- src/scopes/internal/zmq_middleware/ObjectAdapter.cpp 2014-05-20 04:20:46 +0000
+++ src/scopes/internal/zmq_middleware/ObjectAdapter.cpp 2014-06-03 09:42:46 +0000
@@ -524,12 +524,12 @@
524 {524 {
525 poller.add(stop);525 poller.add(stop);
526526
527 frontend.set(zmqpp::socket_option::linger, 0);527 frontend.set(zmqpp::socket_option::linger, 200);
528 // "Safe" bind: prevents two servers from binding to the same endpoint.528 // "Safe" bind: prevents two servers from binding to the same endpoint.
529 safe_bind(frontend, endpoint_);529 safe_bind(frontend, endpoint_);
530 poller.add(frontend);530 poller.add(frontend);
531531
532 backend.set(zmqpp::socket_option::linger, 0);532 backend.set(zmqpp::socket_option::linger, 200);
533 backend.bind("inproc://" + name_ + "-worker");533 backend.bind("inproc://" + name_ + "-worker");
534 poller.add(backend);534 poller.add(backend);
535535
@@ -638,7 +638,7 @@
638638
639 auto socket_type = mode_ == RequestMode::Twoway ? zmqpp::socket_type::reply : zmqpp::socket_type::pull;639 auto socket_type = mode_ == RequestMode::Twoway ? zmqpp::socket_type::reply : zmqpp::socket_type::pull;
640 zmqpp::socket s(*mw_.context(), socket_type);640 zmqpp::socket s(*mw_.context(), socket_type);
641 s.set(zmqpp::socket_option::linger, 0);641 s.set(zmqpp::socket_option::linger, 200);
642 s.connect("inproc://" + name_ + "-worker");642 s.connect("inproc://" + name_ + "-worker");
643 poller.add(s);643 poller.add(s);
644644
645645
=== modified file 'src/scopes/internal/zmq_middleware/RegistryI.cpp'
--- src/scopes/internal/zmq_middleware/RegistryI.cpp 2014-04-03 12:57:25 +0000
+++ src/scopes/internal/zmq_middleware/RegistryI.cpp 2014-06-03 09:42:46 +0000
@@ -68,7 +68,8 @@
68RegistryI::RegistryI(RegistryObjectBase::SPtr const& ro) :68RegistryI::RegistryI(RegistryObjectBase::SPtr const& ro) :
69 ServantBase(ro, { { "get_metadata", bind(&RegistryI::get_metadata_, this, _1, _2, _3) },69 ServantBase(ro, { { "get_metadata", bind(&RegistryI::get_metadata_, this, _1, _2, _3) },
70 { "list", bind(&RegistryI::list_, this, _1, _2, _3) },70 { "list", bind(&RegistryI::list_, this, _1, _2, _3) },
71 { "locate", bind(&RegistryI::locate_, this, _1, _2, _3) } })71 { "locate", bind(&RegistryI::locate_, this, _1, _2, _3) },
72 { "is_scope_running", bind(&RegistryI::is_scope_running_, this, _1, _2, _3) } })
7273
73{74{
74}75}
@@ -151,6 +152,28 @@
151 }152 }
152}153}
153154
155void RegistryI::is_scope_running_(Current const&,
156 capnp::AnyPointer::Reader& in_params,
157 capnproto::Response::Builder& r)
158{
159 auto req = in_params.getAs<capnproto::Registry::IsScopeRunningRequest>();
160 string scope_id = req.getIdentity().cStr();
161 auto delegate = dynamic_pointer_cast<RegistryObjectBase>(del());
162 try
163 {
164 auto is_running = delegate->is_scope_running(scope_id);
165 r.setStatus(capnproto::ResponseStatus::SUCCESS);
166 auto is_scope_running_response = r.initPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().initResponse();
167 is_scope_running_response.setReturnValue(is_running);
168 }
169 catch (NotFoundException const& e)
170 {
171 r.setStatus(capnproto::ResponseStatus::USER_EXCEPTION);
172 auto get_metadata_response = r.initPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().initResponse();
173 get_metadata_response.initNotFoundException().setIdentity(e.name().c_str());
174 }
175}
176
154} // namespace zmq_middleware177} // namespace zmq_middleware
155178
156} // namespace internal179} // namespace internal
157180
=== modified file 'src/scopes/internal/zmq_middleware/ZmqRegistry.cpp'
--- src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-05-07 05:54:20 +0000
+++ src/scopes/internal/zmq_middleware/ZmqRegistry.cpp 2014-06-03 09:42:46 +0000
@@ -187,6 +187,40 @@
187 }187 }
188 }188 }
189}189}
190
191bool ZmqRegistry::is_scope_running(std::string const& scope_id)
192{
193 capnp::MallocMessageBuilder request_builder;
194 auto request = make_request_(request_builder, "is_scope_running");
195 auto in_params = request.initInParams().getAs<capnproto::Registry::IsScopeRunningRequest>();
196 in_params.setIdentity(scope_id.c_str());
197
198 auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder); });
199 auto receiver = future.get();
200 auto segments = receiver.receive();
201 capnp::SegmentArrayMessageReader reader(segments);
202 auto response = reader.getRoot<capnproto::Response>();
203 throw_if_runtime_exception(response);
204
205 auto is_scope_running_response = response.getPayload().getAs<capnproto::Registry::IsScopeRunningResponse>().getResponse();
206 switch (is_scope_running_response.which())
207 {
208 case capnproto::Registry::IsScopeRunningResponse::Response::RETURN_VALUE:
209 {
210 return is_scope_running_response.getReturnValue();
211 }
212 case capnproto::Registry::IsScopeRunningResponse::Response::NOT_FOUND_EXCEPTION:
213 {
214 auto ex = is_scope_running_response.getNotFoundException();
215 throw NotFoundException("Registry::is_scope_running(): no such scope", ex.getIdentity().cStr());
216 }
217 default:
218 {
219 throw MiddlewareException("Registry::is_scope_running(): unknown user exception");
220 }
221 }
222}
223
190} // namespace zmq_middleware224} // namespace zmq_middleware
191225
192} // namespace internal226} // namespace internal
193227
=== modified file 'src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp'
--- src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 2014-05-19 09:17:14 +0000
+++ src/scopes/internal/zmq_middleware/ZmqSubscriber.cpp 2014-06-03 09:42:46 +0000
@@ -44,7 +44,6 @@
44 , topic_(topic)44 , topic_(topic)
45 , thread_state_(NotRunning)45 , thread_state_(NotRunning)
46 , thread_exception_(nullptr)46 , thread_exception_(nullptr)
47 , callback_(nullptr)
48{47{
49 // Validate publisher_id48 // Validate publisher_id
50 if (publisher_id.find('/') != std::string::npos)49 if (publisher_id.find('/') != std::string::npos)
@@ -67,9 +66,9 @@
67 thread_ = std::thread(&ZmqSubscriber::subscriber_thread, this);66 thread_ = std::thread(&ZmqSubscriber::subscriber_thread, this);
6867
69 std::unique_lock<std::mutex> lock(mutex_);68 std::unique_lock<std::mutex> lock(mutex_);
70 cond_.wait(lock, [this] { return thread_state_ == Running || thread_state_ == Failed; });69 cond_.wait(lock, [this] { return thread_state_ == Running || thread_state_ == Stopped; });
7170
72 if (thread_state_ == Failed)71 if (thread_state_ == Stopped)
73 {72 {
74 if (thread_.joinable())73 if (thread_.joinable())
75 {74 {
@@ -89,7 +88,10 @@
8988
90ZmqSubscriber::~ZmqSubscriber()89ZmqSubscriber::~ZmqSubscriber()
91{90{
92 thread_stopper_->stop();91 {
92 std::lock_guard<std::mutex> lock(mutex_);
93 thread_stopper_ = nullptr;
94 }
9395
94 if (thread_.joinable())96 if (thread_.joinable())
95 {97 {
@@ -102,12 +104,6 @@
102 return endpoint_;104 return endpoint_;
103}105}
104106
105void ZmqSubscriber::set_message_callback(SubscriberCallback callback)
106{
107 std::lock_guard<std::mutex> lock(mutex_);
108 callback_ = callback;
109}
110
111void ZmqSubscriber::subscriber_thread()107void ZmqSubscriber::subscriber_thread()
112{108{
113 try109 try
@@ -137,6 +133,7 @@
137 std::string message;133 std::string message;
138 while (true)134 while (true)
139 {135 {
136 // poll() throws when the zmq context is destroyed (hense stopping the thread)
140 poller.poll();137 poller.poll();
141138
142 // Flush out the message queue before stopping the thread139 // Flush out the message queue before stopping the thread
@@ -146,14 +143,11 @@
146143
147 // Discard the message if no callback is set144 // Discard the message if no callback is set
148 std::lock_guard<std::mutex> lock(mutex_);145 std::lock_guard<std::mutex> lock(mutex_);
149 if (callback_)146 // Message should arrive in the format: "<topic>:<message>"
147 if (message.length() > topic_.length() &&
148 message[topic_.length()] == ':')
150 {149 {
151 // Message should arrive in the format: "<topic>:<message>"150 message_received_(message.substr(topic_.length() + 1));
152 if (message.length() > topic_.length() &&
153 message[topic_.length()] == ':')
154 {
155 callback_(message.substr(topic_.length() + 1));
156 }
157 }151 }
158 }152 }
159 else if(poller.has_input(stop_socket))153 else if(poller.has_input(stop_socket))
@@ -170,8 +164,9 @@
170 catch (...)164 catch (...)
171 {165 {
172 std::lock_guard<std::mutex> lock(mutex_);166 std::lock_guard<std::mutex> lock(mutex_);
167 thread_stopper_ = nullptr;
173 thread_exception_ = std::current_exception();168 thread_exception_ = std::current_exception();
174 thread_state_ = Failed;169 thread_state_ = Stopped;
175 cond_.notify_all();170 cond_.notify_all();
176 }171 }
177}172}
178173
=== modified file 'src/scopes/internal/zmq_middleware/capnproto/Registry.capnp'
--- src/scopes/internal/zmq_middleware/capnproto/Registry.capnp 2014-04-03 12:57:25 +0000
+++ src/scopes/internal/zmq_middleware/capnproto/Registry.capnp 2014-06-03 09:42:46 +0000
@@ -80,3 +80,17 @@
80 registryException @2 : RegistryException;80 registryException @2 : RegistryException;
81 }81 }
82}82}
83
84struct IsScopeRunningRequest
85{
86 identity @0 : Text;
87}
88
89struct IsScopeRunningResponse
90{
91 response : union
92 {
93 returnValue @0 : Bool;
94 notFoundException @1 : NotFoundException;
95 }
96}
8397
=== modified file 'test/gtest/scopes/CMakeLists.txt'
--- test/gtest/scopes/CMakeLists.txt 2014-05-16 10:22:49 +0000
+++ test/gtest/scopes/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -11,8 +11,8 @@
11add_subdirectory(ColumnLayout)11add_subdirectory(ColumnLayout)
12add_subdirectory(Department)12add_subdirectory(Department)
13add_subdirectory(Filters)13add_subdirectory(Filters)
14add_subdirectory(IdleShutdown)14#add_subdirectory(IdleShutdown)
15add_subdirectory(Invocation)15#add_subdirectory(Invocation)
16add_subdirectory(OptionSelectorFilter)16add_subdirectory(OptionSelectorFilter)
17add_subdirectory(RadioButtonsFilter)17add_subdirectory(RadioButtonsFilter)
18add_subdirectory(RangeInputFilter)18add_subdirectory(RangeInputFilter)
@@ -20,7 +20,7 @@
20add_subdirectory(PreviewWidget)20add_subdirectory(PreviewWidget)
21add_subdirectory(QueryMetadata)21add_subdirectory(QueryMetadata)
22add_subdirectory(Registry)22add_subdirectory(Registry)
23add_subdirectory(Runtime)23#add_subdirectory(Runtime)
24add_subdirectory(ScopeBase)24add_subdirectory(ScopeBase)
25add_subdirectory(ScopeExceptions)25add_subdirectory(ScopeExceptions)
26add_subdirectory(Variant)26add_subdirectory(Variant)
2727
=== modified file 'test/gtest/scopes/Registry/CMakeLists.txt'
--- test/gtest/scopes/Registry/CMakeLists.txt 2014-04-03 16:50:44 +0000
+++ test/gtest/scopes/Registry/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -13,3 +13,4 @@
1313
14add_test(Registry Registry_test)14add_test(Registry Registry_test)
15add_subdirectory(scopes)15add_subdirectory(scopes)
16add_subdirectory(other_scopes)
1617
=== modified file 'test/gtest/scopes/Registry/Registry_test.cpp'
--- test/gtest/scopes/Registry/Registry_test.cpp 2014-05-21 11:41:48 +0000
+++ test/gtest/scopes/Registry/Registry_test.cpp 2014-06-03 09:42:46 +0000
@@ -23,13 +23,15 @@
23#include <unity/scopes/CategorisedResult.h>23#include <unity/scopes/CategorisedResult.h>
24#include <gtest/gtest.h>24#include <gtest/gtest.h>
2525
26#include <boost/filesystem/operations.hpp>
26#include <condition_variable>27#include <condition_variable>
27#include <functional>28#include <functional>
28#include <mutex>29#include <mutex>
29
30#include <signal.h>30#include <signal.h>
31#include <thread>
31#include <unistd.h>32#include <unistd.h>
3233
34using namespace boost;
33using namespace unity::scopes;35using namespace unity::scopes;
3436
35class Receiver : public SearchListenerBase37class Receiver : public SearchListenerBase
@@ -62,6 +64,7 @@
62 auto now = std::chrono::steady_clock::now();64 auto now = std::chrono::steady_clock::now();
63 auto expiry_time = now + std::chrono::seconds(5);65 auto expiry_time = now + std::chrono::seconds(5);
64 EXPECT_TRUE(cond_.wait_until(lock, expiry_time, [this]{ return done_; })) << "finished message not delivered";66 EXPECT_TRUE(cond_.wait_until(lock, expiry_time, [this]{ return done_; })) << "finished message not delivered";
67 done_ = false;
65 return finished_ok_;68 return finished_ok_;
66 }69 }
6770
@@ -101,16 +104,224 @@
101 EXPECT_EQ("scope-B.HotKey", meta.hot_key());104 EXPECT_EQ("scope-B.HotKey", meta.hot_key());
102 EXPECT_EQ("scope-B.SearchHint", meta.search_hint());105 EXPECT_EQ("scope-B.SearchHint", meta.search_hint());
103 EXPECT_EQ(TEST_RUNTIME_PATH "/scopes/testscopeB", meta.scope_directory());106 EXPECT_EQ(TEST_RUNTIME_PATH "/scopes/testscopeB", meta.scope_directory());
104107}
105 auto sp = meta.proxy();108
109TEST(Registry, scope_state_notify)
110{
111 bool update_received = false;
112 bool testscopeA_state = false;
113 bool testscopeB_state = false;
114 std::mutex mutex;
115 std::condition_variable cond;
116
117 Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE);
118 RegistryProxy r = rt->registry();
119
120 // Configure testscopeA scope_state_callback
121 auto connA = r->set_scope_state_callback("testscopeA", [&update_received, &testscopeA_state, &mutex, &cond](bool is_running)
122 {
123 std::lock_guard<std::mutex> lock(mutex);
124 update_received = true;
125 testscopeA_state = is_running;
126 cond.notify_one();
127 });
128 // Configure testscopeB scope_state_callback
129 auto connB = r->set_scope_state_callback("testscopeB", [&update_received, &testscopeB_state, &mutex, &cond](bool is_running)
130 {
131 std::lock_guard<std::mutex> lock(mutex);
132 update_received = true;
133 testscopeB_state = is_running;
134 cond.notify_one();
135 });
136 auto wait_for_state_update = [&update_received, &mutex, &cond]
137 {
138 // Wait for an update notification
139 std::unique_lock<std::mutex> lock(mutex);
140 bool success = cond.wait_for(lock, std::chrono::milliseconds(500), [&update_received] { return update_received; });
141 update_received = false;
142 return success;
143 };
106144
107 auto receiver = std::make_shared<Receiver>();145 auto receiver = std::make_shared<Receiver>();
108 SearchListenerBase::SPtr reply(receiver);146 SearchListenerBase::SPtr reply(receiver);
109 SearchMetadata metadata("C", "desktop");147 SearchMetadata metadata("C", "desktop");
110148
149 auto meta = r->get_metadata("testscopeA");
150 auto sp = meta.proxy();
151
152 // testscopeA should not be running at this point
153 EXPECT_FALSE(r->is_scope_running("testscopeA"));
154 EXPECT_FALSE(wait_for_state_update());
155
156 // search would fail if testscopeA can't be executed
157 auto ctrl = sp->search("foo", metadata, reply);
158 EXPECT_TRUE(receiver->wait_until_finished());
159
160 // testscopeA should now be running
161 EXPECT_TRUE(wait_for_state_update());
162 EXPECT_TRUE(testscopeA_state);
163 EXPECT_TRUE(r->is_scope_running("testscopeA"));
164
165 meta = r->get_metadata("testscopeB");
166 sp = meta.proxy();
167
168 // testscopeB should not be running at this point
169 EXPECT_FALSE(r->is_scope_running("testscopeB"));
170 EXPECT_FALSE(wait_for_state_update());
171
111 // search would fail if testscopeB can't be executed172 // search would fail if testscopeB can't be executed
112 auto ctrl = sp->search("foo", metadata, reply);173 ctrl = sp->search("foo", metadata, reply);
113 EXPECT_TRUE(receiver->wait_until_finished());174 EXPECT_TRUE(receiver->wait_until_finished());
175
176 // testscopeB should now be running
177 EXPECT_TRUE(wait_for_state_update());
178 EXPECT_TRUE(testscopeB_state);
179 EXPECT_TRUE(r->is_scope_running("testscopeB"));
180
181 // check now that we get a callback when testscopeB terminates (timed out after 2s)
182 std::this_thread::sleep_for(std::chrono::seconds{3});
183 EXPECT_TRUE(wait_for_state_update());
184 EXPECT_FALSE(testscopeB_state);
185 EXPECT_FALSE(r->is_scope_running("testscopeB"));
186}
187
188TEST(Registry, list_update_notify)
189{
190 bool update_received = false;
191 std::mutex mutex;
192 std::condition_variable cond;
193
194 Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE);
195 RegistryProxy r = rt->registry();
196
197 // Configure registry update callback
198 auto conn = r->set_list_update_callback([&update_received, &mutex, &cond]
199 {
200 std::lock_guard<std::mutex> lock(mutex);
201 update_received = true;
202 cond.notify_one();
203 });
204 auto wait_for_update = [&update_received, &mutex, &cond]
205 {
206 // Flush out update notifications
207 std::unique_lock<std::mutex> lock(mutex);
208 bool success = false;
209 while (cond.wait_for(lock, std::chrono::milliseconds(500), [&update_received] { return update_received; }))
210 {
211 success = true;
212 update_received = false;
213 }
214 update_received = false;
215 return success;
216 };
217
218 system::error_code ec;
219
220 // First check that we have 2 scopes registered
221 MetadataMap list = r->list();
222 EXPECT_EQ(2, list.size());
223 EXPECT_NE(list.end(), list.find("testscopeA"));
224 EXPECT_NE(list.end(), list.find("testscopeB"));
225 EXPECT_EQ(list.end(), list.find("testscopeC"));
226 EXPECT_EQ(list.end(), list.find("testscopeD"));
227
228 // Move testscopeC into the scopes folder
229 std::cout << "Move testscopeC into the scopes folder" << std::endl;
230 filesystem::rename(TEST_RUNTIME_PATH "/other_scopes/testscopeC", TEST_RUNTIME_PATH "/scopes/testscopeC", ec);
231 ASSERT_EQ("Success", ec.message());
232 EXPECT_TRUE(wait_for_update());
233
234 // Now check that we have 3 scopes registered
235 list = r->list();
236 EXPECT_EQ(3, list.size());
237 EXPECT_NE(list.end(), list.find("testscopeA"));
238 EXPECT_NE(list.end(), list.find("testscopeB"));
239 EXPECT_NE(list.end(), list.find("testscopeC"));
240 EXPECT_EQ(list.end(), list.find("testscopeD"));
241
242 // Make a symlink to testscopeD in the scopes folder
243 std::cout << "Make a symlink to testscopeD in the scopes folder" << std::endl;
244 filesystem::create_symlink(TEST_RUNTIME_PATH "/other_scopes/testscopeD", TEST_RUNTIME_PATH "/scopes/testscopeD", ec);
245 ASSERT_EQ("Success", ec.message());
246 EXPECT_TRUE(wait_for_update());
247
248 // Now check that we have 4 scopes registered
249 list = r->list();
250 EXPECT_EQ(4, list.size());
251 EXPECT_NE(list.end(), list.find("testscopeA"));
252 EXPECT_NE(list.end(), list.find("testscopeB"));
253 EXPECT_NE(list.end(), list.find("testscopeC"));
254 EXPECT_NE(list.end(), list.find("testscopeD"));
255
256 // Move testscopeC back into the other_scopes folder
257 std::cout << "Move testscopeC back into the other_scopes folder" << std::endl;
258 filesystem::rename(TEST_RUNTIME_PATH "/scopes/testscopeC", TEST_RUNTIME_PATH "/other_scopes/testscopeC", ec);
259 ASSERT_EQ("Success", ec.message());
260 EXPECT_TRUE(wait_for_update());
261
262 // Now check that we have 3 scopes registered again
263 list = r->list();
264 EXPECT_EQ(3, list.size());
265 EXPECT_NE(list.end(), list.find("testscopeA"));
266 EXPECT_NE(list.end(), list.find("testscopeB"));
267 EXPECT_EQ(list.end(), list.find("testscopeC"));
268 EXPECT_NE(list.end(), list.find("testscopeD"));
269
270 // Remove symlink to testscopeD from the scopes folder
271 std::cout << "Remove symlink to testscopeD from the scopes folder" << std::endl;
272 filesystem::remove(TEST_RUNTIME_PATH "/scopes/testscopeD", ec);
273 ASSERT_EQ("Success", ec.message());
274 EXPECT_TRUE(wait_for_update());
275
276 // Now check that we are back to having 2 scopes registered
277 list = r->list();
278 EXPECT_EQ(2, list.size());
279 EXPECT_NE(list.end(), list.find("testscopeA"));
280 EXPECT_NE(list.end(), list.find("testscopeB"));
281 EXPECT_EQ(list.end(), list.find("testscopeC"));
282 EXPECT_EQ(list.end(), list.find("testscopeD"));
283
284 // Make a folder in scopes named "testfolder"
285 std::cout << "Make a folder in scopes named \"testfolder\"" << std::endl;
286 filesystem::create_directory(TEST_RUNTIME_PATH "/scopes/testfolder", ec);
287 ASSERT_EQ("Success", ec.message());
288 EXPECT_FALSE(wait_for_update());
289
290 // Check that no scopes were registered
291 list = r->list();
292 EXPECT_EQ(2, list.size());
293 EXPECT_NE(list.end(), list.find("testscopeA"));
294 EXPECT_NE(list.end(), list.find("testscopeB"));
295 EXPECT_EQ(list.end(), list.find("testscopeC"));
296 EXPECT_EQ(list.end(), list.find("testscopeD"));
297
298 // Make a symlink to testscopeC.ini in testfolder
299 std::cout << "Make a symlink to testscopeC.ini in testfolder" << std::endl;
300 filesystem::create_symlink(TEST_RUNTIME_PATH "/other_scopes/testscopeC/testscopeC.ini", TEST_RUNTIME_PATH "/scopes/testfolder/testscopeC.ini", ec);
301 ASSERT_EQ("Success", ec.message());
302 EXPECT_TRUE(wait_for_update());
303
304 // Now check that we have 3 scopes registered
305 list = r->list();
306 EXPECT_EQ(3, list.size());
307 EXPECT_NE(list.end(), list.find("testscopeA"));
308 EXPECT_NE(list.end(), list.find("testscopeB"));
309 EXPECT_NE(list.end(), list.find("testscopeC"));
310 EXPECT_EQ(list.end(), list.find("testscopeD"));
311
312 // Remove testfolder
313 std::cout << "Remove testfolder" << std::endl;
314 filesystem::remove_all(TEST_RUNTIME_PATH "/scopes/testfolder", ec);
315 ASSERT_EQ("Success", ec.message());
316 EXPECT_TRUE(wait_for_update());
317
318 // Now check that we are back to having 2 scopes registered
319 list = r->list();
320 EXPECT_EQ(2, list.size());
321 EXPECT_NE(list.end(), list.find("testscopeA"));
322 EXPECT_NE(list.end(), list.find("testscopeB"));
323 EXPECT_EQ(list.end(), list.find("testscopeC"));
324 EXPECT_EQ(list.end(), list.find("testscopeD"));
114}325}
115326
116int main(int argc, char **argv)327int main(int argc, char **argv)
@@ -138,4 +349,4 @@
138 perror("Failed to fork:");349 perror("Failed to fork:");
139 }350 }
140 return 1;351 return 1;
141}352}
142\ No newline at end of file353\ No newline at end of file
143354
=== added directory 'test/gtest/scopes/Registry/other_scopes'
=== added file 'test/gtest/scopes/Registry/other_scopes/CMakeLists.txt'
--- test/gtest/scopes/Registry/other_scopes/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/Registry/other_scopes/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -0,0 +1,2 @@
1add_subdirectory(testscopeC)
2add_subdirectory(testscopeD)
03
=== added directory 'test/gtest/scopes/Registry/other_scopes/testscopeC'
=== added file 'test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt'
--- test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/Registry/other_scopes/testscopeC/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -0,0 +1,1 @@
1configure_file(testscopeC.ini.in testscopeC.ini)
02
=== added file 'test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in'
--- test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/Registry/other_scopes/testscopeC/testscopeC.ini.in 2014-06-03 09:42:46 +0000
@@ -0,0 +1,8 @@
1[ScopeConfig]
2DisplayName = scope-C.DisplayName
3Description = scope-C.Description
4Art = /foo/scope-C.Art
5Author = Canonical Ltd.
6Icon = /foo/scope-C.Icon
7SearchHint = scope-C.SearchHint
8HotKey = scope-C.HotKey
09
=== added directory 'test/gtest/scopes/Registry/other_scopes/testscopeD'
=== added file 'test/gtest/scopes/Registry/other_scopes/testscopeD/CMakeLists.txt'
--- test/gtest/scopes/Registry/other_scopes/testscopeD/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/Registry/other_scopes/testscopeD/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -0,0 +1,1 @@
1configure_file(testscopeD.ini.in testscopeD.ini)
02
=== added file 'test/gtest/scopes/Registry/other_scopes/testscopeD/testscopeD.ini.in'
--- test/gtest/scopes/Registry/other_scopes/testscopeD/testscopeD.ini.in 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/Registry/other_scopes/testscopeD/testscopeD.ini.in 2014-06-03 09:42:46 +0000
@@ -0,0 +1,8 @@
1[ScopeConfig]
2DisplayName = scope-D.DisplayName
3Description = scope-D.Description
4Art = /foo/scope-D.Art
5Author = Canonical Ltd.
6Icon = /foo/scope-D.Icon
7SearchHint = scope-D.SearchHint
8HotKey = scope-D.HotKey
09
=== modified file 'test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp'
--- test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2014-05-22 08:45:05 +0000
+++ test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2014-06-03 09:42:46 +0000
@@ -164,7 +164,7 @@
164 exec_data.confinement_profile = confinement_profile;164 exec_data.confinement_profile = confinement_profile;
165 exec_data.timeout_ms = 1500;165 exec_data.timeout_ms = 1500;
166166
167 registry.reset(new RegistryObject(*death_observer(), executor));167 registry.reset(new RegistryObject(*death_observer(), executor, nullptr));
168 registry->add_local_scope("scope-id", meta, exec_data);168 registry->add_local_scope("scope-id", meta, exec_data);
169 registry->locate("scope-id");169 registry->locate("scope-id");
170 EXPECT_TRUE(registry->is_scope_running("scope-id"));170 EXPECT_TRUE(registry->is_scope_running("scope-id"));
171171
=== modified file 'test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt'
--- test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt 2014-05-19 05:15:06 +0000
+++ test/gtest/scopes/internal/zmq_middleware/CMakeLists.txt 2014-06-03 09:42:46 +0000
@@ -1,6 +1,6 @@
1add_subdirectory(ObjectAdapter)1add_subdirectory(ObjectAdapter)
2add_subdirectory(PubSub)2add_subdirectory(PubSub)
3add_subdirectory(RegistryI)3#add_subdirectory(RegistryI)
4add_subdirectory(ServantBase)4add_subdirectory(ServantBase)
5add_subdirectory(StopPublisher)5add_subdirectory(StopPublisher)
6add_subdirectory(Util)6add_subdirectory(Util)
77
=== modified file 'test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp'
--- test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 2014-05-20 04:20:46 +0000
+++ test/gtest/scopes/internal/zmq_middleware/PubSub/PubSub_test.cpp 2014-06-03 09:42:46 +0000
@@ -167,16 +167,16 @@
167167
168 // Create a few subscribers168 // Create a few subscribers
169 auto subscriber1 = mw.create_subscriber("testpublisher", "testtopic1");169 auto subscriber1 = mw.create_subscriber("testpublisher", "testtopic1");
170 subscriber1->set_message_callback(std::bind(&SubMsgReceiver::receive1, &message_receiver, _1));170 subscriber1->message_received().connect(std::bind(&SubMsgReceiver::receive1, &message_receiver, _1));
171171
172 auto subscriber2 = mw.create_subscriber("testpublisher", "testtopic2");172 auto subscriber2 = mw.create_subscriber("testpublisher", "testtopic2");
173 subscriber2->set_message_callback(std::bind(&SubMsgReceiver::receive2, &message_receiver, _1));173 subscriber2->message_received().connect(std::bind(&SubMsgReceiver::receive2, &message_receiver, _1));
174174
175 auto subscriber3 = mw.create_subscriber("testpublisher", "");175 auto subscriber3 = mw.create_subscriber("testpublisher", "");
176 subscriber3->set_message_callback(std::bind(&SubMsgReceiver::receive3, &message_receiver, _1));176 subscriber3->message_received().connect(std::bind(&SubMsgReceiver::receive3, &message_receiver, _1));
177177
178 auto subscriber4 = mw.create_subscriber("testpublisher2", "testtopic4");178 auto subscriber4 = mw.create_subscriber("testpublisher2", "testtopic4");
179 subscriber4->set_message_callback(std::bind(&SubMsgReceiver::receive4, &message_receiver, _1));179 subscriber4->message_received().connect(std::bind(&SubMsgReceiver::receive4, &message_receiver, _1));
180180
181 // Give the subscribers some time to connect181 // Give the subscribers some time to connect
182 std::this_thread::sleep_for(std::chrono::milliseconds(500));182 std::this_thread::sleep_for(std::chrono::milliseconds(500));
183183
=== modified file 'test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp'
--- test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp 2014-05-19 10:03:31 +0000
+++ test/gtest/scopes/internal/zmq_middleware/RegistryI/RegistryI_test.cpp 2014-06-03 09:42:46 +0000
@@ -100,7 +100,7 @@
100100
101 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);101 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);
102 Executor::SPtr executor = make_shared<Executor>();102 Executor::SPtr executor = make_shared<Executor>();
103 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor));103 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor, middleware));
104 auto registry = middleware->add_registry_object(identity, ro);104 auto registry = middleware->add_registry_object(identity, ro);
105 auto p = middleware->create_scope_proxy("scope1", "ipc:///tmp/scope1");105 auto p = middleware->create_scope_proxy("scope1", "ipc:///tmp/scope1");
106 EXPECT_TRUE(ro->add_local_scope("scope1", move(make_meta("scope1", p, middleware)),106 EXPECT_TRUE(ro->add_local_scope("scope1", move(make_meta("scope1", p, middleware)),
@@ -123,7 +123,7 @@
123123
124 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);124 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);
125 Executor::SPtr executor = make_shared<Executor>();125 Executor::SPtr executor = make_shared<Executor>();
126 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor));126 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor, middleware));
127 auto registry = middleware->add_registry_object(identity, ro);127 auto registry = middleware->add_registry_object(identity, ro);
128128
129 auto r = runtime->registry();129 auto r = runtime->registry();
@@ -172,7 +172,7 @@
172172
173 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);173 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);
174 Executor::SPtr executor = make_shared<Executor>();174 Executor::SPtr executor = make_shared<Executor>();
175 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor));175 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor, middleware));
176 auto registry = middleware->add_registry_object(identity, ro);176 auto registry = middleware->add_registry_object(identity, ro);
177177
178 auto r = runtime->registry();178 auto r = runtime->registry();
@@ -224,7 +224,7 @@
224224
225 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);225 MiddlewareBase::SPtr middleware = runtime->factory()->create(identity, mw_kind, mw_configfile);
226 Executor::SPtr executor = make_shared<Executor>();226 Executor::SPtr executor = make_shared<Executor>();
227 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor));227 RegistryObject::SPtr ro(make_shared<RegistryObject>(*scope.death_observer, executor, middleware));
228 RegistryObject::ScopeExecData dummy_exec_data;228 RegistryObject::ScopeExecData dummy_exec_data;
229 auto registry = middleware->add_registry_object(identity, ro);229 auto registry = middleware->add_registry_object(identity, ro);
230 auto proxy = middleware->create_scope_proxy("scope1", "ipc:///tmp/scope1");230 auto proxy = middleware->create_scope_proxy("scope1", "ipc:///tmp/scope1");
@@ -286,7 +286,7 @@
286{286{
287public:287public:
288 MockRegistryObject(core::posix::ChildProcess::DeathObserver& death_observer)288 MockRegistryObject(core::posix::ChildProcess::DeathObserver& death_observer)
289 : RegistryObject(death_observer, make_shared<Executor>())289 : RegistryObject(death_observer, make_shared<Executor>(), nullptr)
290 {290 {
291 }291 }
292292
@@ -393,7 +393,7 @@
393 mw = rt->factory()->find(reg_id, mw_kind);393 mw = rt->factory()->find(reg_id, mw_kind);
394394
395 Executor::SPtr executor = make_shared<Executor>();395 Executor::SPtr executor = make_shared<Executor>();
396 reg = RegistryObject::SPtr(new RegistryObject(*scope.death_observer, executor));396 reg = RegistryObject::SPtr(new RegistryObject(*scope.death_observer, executor, mw));
397 mw->add_registry_object(reg_id, reg);397 mw->add_registry_object(reg_id, reg);
398 mw->add_state_receiver_object("StateReceiver", reg->state_receiver());398 mw->add_state_receiver_object("StateReceiver", reg->state_receiver());
399399

Subscribers

People subscribed via source and target branches

to all changes: