Merge lp:~marcustomlinson/unity-scopes-api/disable_timeouts_in_debug_mode into lp:unity-scopes-api/devel

Proposed by Marcus Tomlinson
Status: Merged
Approved by: Michi Henning
Approved revision: 609
Merged at revision: 608
Proposed branch: lp:~marcustomlinson/unity-scopes-api/disable_timeouts_in_debug_mode
Merge into: lp:unity-scopes-api/devel
Prerequisite: lp:~marcustomlinson/unity-scopes-api/revert_debug_timeout_config_params
Diff against target: 131 lines (+39/-19)
5 files modified
include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h (+3/-1)
scoperegistry/scoperegistry.cpp (+2/-2)
src/scopes/internal/RegistryObject.cpp (+11/-3)
src/scopes/internal/zmq_middleware/ZmqObject.cpp (+9/-9)
src/scopes/internal/zmq_middleware/ZmqScope.cpp (+14/-4)
To merge this branch: bzr merge lp:~marcustomlinson/unity-scopes-api/disable_timeouts_in_debug_mode
Reviewer Review Type Date Requested Status
Michi Henning (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Paweł Stołowski (community) Needs Information
Review via email: mp+263500@code.launchpad.net

Commit message

Disable process and locate timeouts completely in debug mode

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Paweł Stołowski (stolowski) wrote :

102 - auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, -1, 30000); });
103 + auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, -1, -1); });

This change looks a bit suspicious, is this intended? In full context it is:

    if (!debug_mode_)
    {
        capnp::MallocMessageBuilder request_builder;
        make_request_(request_builder, "debug_mode");

        auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, -1, -1); });

Which, if I understand it correctly, means we don't apply timeout when running normally (i.e. not in debug mode)?

review: Needs Information
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

> 102 - auto future = mw_base()->twoway_pool()->submit([&] { return
> this->invoke_twoway_(request_builder, -1, 30000); });
> 103 + auto future = mw_base()->twoway_pool()->submit([&] { return
> this->invoke_twoway_(request_builder, -1, -1); });
>
> This change looks a bit suspicious, is this intended? In full context it is:
>
> if (!debug_mode_)
> {
> capnp::MallocMessageBuilder request_builder;
> make_request_(request_builder, "debug_mode");
>
> auto future = mw_base()->twoway_pool()->submit([&] { return
> this->invoke_twoway_(request_builder, -1, -1); });
>
> Which, if I understand it correctly, means we don't apply timeout when running
> normally (i.e. not in debug mode)?

So the timeout we're disabling here is the locate() call that happens implicitly when making any request. It goes:
    1. reg->locate(scope) - first ensure the scope is running
    2. scope->debug_mode() - make the actual request

The issue there is if a scope actually is in debug mode and it takes long to start up, that implicit locate() call will time out prematurely.

In the situation where a scope is not in debug mode but starts up slowly (E.g. has a breakpoint in start()), the registry's own "Process.Timeout" will kick in (which is configured according to the "DebugMode" state of each scope config as they are added). Meaning, that implicit locate() call will actually still timeout due to the registry's "Process.Timeout" constraint when a regular scope takes too long to start.

Make sense?

609. By Marcus Tomlinson

Added comment on why we disable locate() timeout on debug_mode request.
Also fixed my mistake of disabling the two-way timeout there aswell (oops).

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

> > 102 - auto future = mw_base()->twoway_pool()->submit([&] { return
> > this->invoke_twoway_(request_builder, -1, 30000); });
> > 103 + auto future = mw_base()->twoway_pool()->submit([&] { return
> > this->invoke_twoway_(request_builder, -1, -1); });
> >
> > This change looks a bit suspicious, is this intended? In full context it is:
> >
> > if (!debug_mode_)
> > {
> > capnp::MallocMessageBuilder request_builder;
> > make_request_(request_builder, "debug_mode");
> >
> > auto future = mw_base()->twoway_pool()->submit([&] { return
> > this->invoke_twoway_(request_builder, -1, -1); });
> >
> > Which, if I understand it correctly, means we don't apply timeout when
> running
> > normally (i.e. not in debug mode)?
>
> So the timeout we're disabling here is the locate() call that happens
> implicitly when making any request. It goes:
> 1. reg->locate(scope) - first ensure the scope is running
> 2. scope->debug_mode() - make the actual request
>
> The issue there is if a scope actually is in debug mode and it takes long to
> start up, that implicit locate() call will time out prematurely.
>
> In the situation where a scope is not in debug mode but starts up slowly (E.g.
> has a breakpoint in start()), the registry's own "Process.Timeout" will kick
> in (which is configured according to the "DebugMode" state of each scope
> config as they are added). Meaning, that implicit locate() call will actually
> still timeout due to the registry's "Process.Timeout" constraint when a
> regular scope takes too long to start.
>
> Make sense?

Sorry, that was a little confusing (even to me) :P Add a comment to the code.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

Looks good to me. Thanks for the comment, that really made a huge difference!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h'
--- include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h 2015-02-09 02:23:22 +0000
+++ include/unity/scopes/internal/zmq_middleware/ZmqObjectProxy.h 2015-07-01 16:48:22 +0000
@@ -91,8 +91,10 @@
9191
92 TwowayOutParams invoke_twoway_(capnp::MessageBuilder& request);92 TwowayOutParams invoke_twoway_(capnp::MessageBuilder& request);
93 TwowayOutParams invoke_twoway_(capnp::MessageBuilder& request,93 TwowayOutParams invoke_twoway_(capnp::MessageBuilder& request,
94 int64_t twoway_timeout);
95 TwowayOutParams invoke_twoway_(capnp::MessageBuilder& request,
94 int64_t twoway_timeout,96 int64_t twoway_timeout,
95 int64_t locate_timeout = -1);97 int64_t locate_timeout);
9698
97private:99private:
98 TwowayOutParams invoke_twoway__(capnp::MessageBuilder& request, int64_t timeout);100 TwowayOutParams invoke_twoway__(capnp::MessageBuilder& request, int64_t timeout);
99101
=== modified file 'scoperegistry/scoperegistry.cpp'
--- scoperegistry/scoperegistry.cpp 2015-07-01 10:59:49 +0000
+++ scoperegistry/scoperegistry.cpp 2015-07-01 16:48:22 +0000
@@ -423,10 +423,10 @@
423 scope_dir.filename().native();423 scope_dir.filename().native();
424 }424 }
425425
426 // Check if this scope has requested debug mode, if so, set the process timeout to 30s426 // Check if this scope has requested debug mode, if so, disable process timeout
427 if (sc.debug_mode())427 if (sc.debug_mode())
428 {428 {
429 exec_data.timeout_ms = 30000;429 exec_data.timeout_ms = -1;
430 }430 }
431 else431 else
432 {432 {
433433
=== modified file 'src/scopes/internal/RegistryObject.cpp'
--- src/scopes/internal/RegistryObject.cpp 2015-04-23 10:11:51 +0000
+++ src/scopes/internal/RegistryObject.cpp 2015-07-01 16:48:22 +0000
@@ -736,9 +736,17 @@
736736
737bool RegistryObject::ScopeProcess::wait_for_state(std::unique_lock<std::mutex>& lock, ProcessState state) const737bool RegistryObject::ScopeProcess::wait_for_state(std::unique_lock<std::mutex>& lock, ProcessState state) const
738{738{
739 return state_change_cond_.wait_for(lock,739 if (exec_data_.timeout_ms == -1)
740 std::chrono::milliseconds(exec_data_.timeout_ms),740 {
741 [this, &state]{return state_ == state;});741 state_change_cond_.wait(lock, [this, &state]{return state_ == state;});
742 return true;
743 }
744 else
745 {
746 return state_change_cond_.wait_for(lock,
747 std::chrono::milliseconds(exec_data_.timeout_ms),
748 [this, &state]{return state_ == state;});
749 }
742}750}
743751
744void RegistryObject::ScopeProcess::kill(std::unique_lock<std::mutex>& lock)752void RegistryObject::ScopeProcess::kill(std::unique_lock<std::mutex>& lock)
745753
=== modified file 'src/scopes/internal/zmq_middleware/ZmqObject.cpp'
--- src/scopes/internal/zmq_middleware/ZmqObject.cpp 2015-01-06 01:05:48 +0000
+++ src/scopes/internal/zmq_middleware/ZmqObject.cpp 2015-07-01 16:48:22 +0000
@@ -190,7 +190,13 @@
190190
191ZmqObjectProxy::TwowayOutParams ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& request)191ZmqObjectProxy::TwowayOutParams ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& request)
192{192{
193 return invoke_twoway_(request, timeout_);193 return invoke_twoway_(request, timeout_, mw_base()->locate_timeout());
194}
195
196ZmqObjectProxy::TwowayOutParams ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& request,
197 int64_t twoway_timeout)
198{
199 return invoke_twoway_(request, twoway_timeout, mw_base()->locate_timeout());
194}200}
195201
196ZmqObjectProxy::TwowayOutParams ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& request,202ZmqObjectProxy::TwowayOutParams ZmqObjectProxy::invoke_twoway_(capnp::MessageBuilder& request,
@@ -211,14 +217,8 @@
211 try217 try
212 {218 {
213 ObjectProxy new_proxy;219 ObjectProxy new_proxy;
214 if (locate_timeout != -1)220 new_proxy = registry_proxy->locate(identity(), locate_timeout);
215 {221
216 new_proxy = registry_proxy->locate(identity(), locate_timeout);
217 }
218 else
219 {
220 new_proxy = registry_proxy->locate(identity());
221 }
222 // update our proxy with the newly received data222 // update our proxy with the newly received data
223 // (we need to first store values in local variables outside of the mutex,223 // (we need to first store values in local variables outside of the mutex,
224 // otherwise we will deadlock on the following ZmqObjectProxy methods)224 // otherwise we will deadlock on the following ZmqObjectProxy methods)
225225
=== modified file 'src/scopes/internal/zmq_middleware/ZmqScope.cpp'
--- src/scopes/internal/zmq_middleware/ZmqScope.cpp 2015-07-01 10:59:49 +0000
+++ src/scopes/internal/zmq_middleware/ZmqScope.cpp 2015-07-01 16:48:22 +0000
@@ -325,7 +325,18 @@
325 capnp::MallocMessageBuilder request_builder;325 capnp::MallocMessageBuilder request_builder;
326 make_request_(request_builder, "debug_mode");326 make_request_(request_builder, "debug_mode");
327327
328 auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, -1, 30000); });328 // When making any two-way request there is an implicit locate() call made to the registry to first ensure that
329 // the scope is actually running - I.e. 1. reg->locate(scope), 2. scope->request().
330
331 // Here we are trying to determine whether the target scope is in debug mode, hence we cannot assume upfront
332 // that it will start up within the regular timeout constraint. Therefore we need to disable the locate()
333 // timeout here to allow enough time for debugged scopes to reply.
334
335 // In the situation where a scope is not in debug mode but starts up slowly, the registry's own
336 // "Process.Timeout" will kick in, meaning that the implicit locate() call will return at a regular timeout for
337 // regular scopes, and will not timeout for debugged scopes.
338
339 auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_twoway_(request_builder, timeout(), -1); });
329 auto out_params = future.get();340 auto out_params = future.get();
330 auto response = out_params.reader->getRoot<capnproto::Response>();341 auto response = out_params.reader->getRoot<capnproto::Response>();
331 throw_if_runtime_exception(response);342 throw_if_runtime_exception(response);
@@ -344,11 +355,10 @@
344355
345ZmqObjectProxy::TwowayOutParams ZmqScope::invoke_scope_(capnp::MessageBuilder& in_params, int64_t timeout)356ZmqObjectProxy::TwowayOutParams ZmqScope::invoke_scope_(capnp::MessageBuilder& in_params, int64_t timeout)
346{357{
347 // Check if this scope has requested debug mode, if so, disable two-way timeout and set358 // Check if this scope has requested debug mode, if so, disable two-way and locate timeouts.
348 // locate timeout to 30s.
349 if (debug_mode())359 if (debug_mode())
350 {360 {
351 return this->invoke_twoway_(in_params, -1, 30000);361 return this->invoke_twoway_(in_params, -1, -1);
352 }362 }
353 return this->invoke_twoway_(in_params, timeout);363 return this->invoke_twoway_(in_params, timeout);
354}364}

Subscribers

People subscribed via source and target branches

to all changes: