Bug #8125

lost-tuple bug and fix for Rinda::TupleSpaceProxy.take

Added by Joel VanderWerf about 1 year ago. Updated about 1 year ago.

[ruby-core:53552]
Status:Closed
Priority:Normal
Assignee:Eric Hodel
Category:lib
Target version:-
ruby -v:ruby 2.0.0p0 (2013-02-24) [x86_64-linux] Backport:

Description

=begin

Rinda::TupleSpaceProxy prevents tuple loss during #take by exposing a "port" object on the client that the remote side (the tuplespace server) pushes to, instead of relying on the method return value. Pushing to the port fails if the process that called #take has exited, so the tuple will not be deleted from the tuplespace server.

However, if the process has not exited, and the thread that called #take was interrupted, the port still exists and accepts push requests (in the main drb thread). In this case the tuple is deleted on the server and not available on the client.

This is frequently a problem when using irb and manually interrupting take calls. It would also be a problem when using timeouts.

A concise reproduction of the problem is in the attached thread-int.rb.

The bug can be fixed by the patch below, which replaces the port array with a custom object that rejects pushes if the call stack has been unwound.

Note that this patch combines naturally with the faster take patch in #8119.

diff --git a/lib/rinda/rinda.rb b/lib/rinda/rinda.rb
index 18e284a..057c61a 100644
--- a/lib/rinda/rinda.rb
+++ b/lib/rinda/rinda.rb
@@ -206,6 +206,23 @@ module Rinda
# TupleSpaceProxy allows a remote Tuplespace to appear as local.

 class TupleSpaceProxy
  • class Port
  • attr_reader :val +
  • def initialize
  • @open = true
  • end

  • def close
  • @open = false
  • end +
  • def push val
  • raise unless @open
  • @val = val
  • nil # so that val doesn't get marshalled again
  • end
  • end

    ##
    # Creates a new TupleSpaceProxy to wrap +ts+.
    @@ -222,6 +239,19 @@ module Rinda
    end

    ##

  • # Safely takes +tuple+ from the proxied TupleSpace. See TupleSpace#take.

  • # Ensures that an interrupted thread will not become a lasting cause

  • # of further data loss.
    +

  • def take_safely(tuple, sec=nil, &block)

  •  port = Port.new
    
  •  @ts.move(DRbObject.new(port), tuple, sec, &block)
    
  •  port.val
    
  • ensure

  •  port.close # don't let the DRb thread push to it when remote sends tuple
    
  • end
    +

  • ##
    # Takes +tuple+ from the proxied TupleSpace. See TupleSpace#take.

    def take(tuple, sec=nil, &block)

=end

thread-int.rb Magnifier (1.1 KB) Joel VanderWerf, 03/20/2013 02:21 AM

rinda.rb.8215.patch Magnifier (2.84 KB) Eric Hodel, 03/23/2013 04:21 PM

rinda.rb.8215.2.patch Magnifier (2.84 KB) Eric Hodel, 03/23/2013 04:26 PM

rinda.rb.8215.3.patch Magnifier (2.91 KB) Eric Hodel, 03/23/2013 04:37 PM

Associated revisions

Revision 39890
Added by Eric Hodel about 1 year ago

  • lib/rinda/rinda.rb: Fixed loss of tuple when remote is alive but the call stack was unwound. Patch by Joel VanderWerf. [ruby-trunk - Bug #8125]
    • test/rinda/test_rinda.rb: Test for the above.

Revision 39923
Added by Eric Hodel about 1 year ago

  • lib/rinda/tuplespace.rb: Only return tuple entry once on move, either through port or regular return, not both. This results in a 120% speedup when combined with #8125. Patch by Joel VanderWerf. [ruby-trunk - Feature #8119]

History

#1 Updated by Hiroshi SHIBATA about 1 year ago

  • Assignee set to Masatoshi Seki

#2 Updated by Eric Hodel about 1 year ago

I think the safe take should be the default take.

I updated your patch and converted thread-int.rb into a test.

#3 Updated by Eric Hodel about 1 year ago

Here is an updated patch that matches the rinda style and removes a leftover p

#4 Updated by Eric Hodel about 1 year ago

Oops, I forgot to run all the tests, this fixes the remaining tests by restoring an accidentally deleted line.

#5 Updated by Masatoshi Seki about 1 year ago

  • Assignee changed from Masatoshi Seki to Eric Hodel

please commit it!

#6 Updated by Eric Hodel about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39890.
Joel, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • lib/rinda/rinda.rb: Fixed loss of tuple when remote is alive but the call stack was unwound. Patch by Joel VanderWerf. [ruby-trunk - Bug #8125]
    • test/rinda/test_rinda.rb: Test for the above.

Also available in: Atom PDF