On Wednesday, February 29, 2012 2:22:27 PM UTC-8, Nels Nelson wrote:
>
> According to the documentation (http://sequel.rubyforge.org/rdoc-
> plugins/classes/Sequel/Plugins/IdentityMap.html<http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/IdentityMap.html>)
>
> the Identity Map
> plugin for Ruby Sequel does not work with rcte_tree?
>
> "The identity_map plugin is not compatible with the eager loading in
> the rcte_tree plugin."
>
> Is this true? Because I have found that it seems to work when doing
> simple things like this:
>
> a = Thing[1]
> b = Thing[2]
>
> a.add_child b
>
> x = Thing[2] # different object?
> a.children.include? x # => true
> a.children.first.object_id == x.object_id # => true
>
>
In general it works. It's only eager loading that does not work, and you
aren't doing eager loading there. The following would probably not work:
Thing.filter(:id=>2).eager(:children).all.first
> However, recently I have encountered a serious issue with the design
> of a system wherein attempting to get important properties of an
> entity retrieved from a tree relationship in my Postgres schema fails
> because the properties have been assigned at runtime are not
> persistent, so the routines in other threads within the system that
> are attempting to access the non-persistent information on those
> objects fail because the identity map does not succeed in returning
> references to the entity instance already marshaled elsewhere in the
> system.
>
> That's a little convoluted, perhaps.
>
>
If I understand you correctly, you want multiple threads to be able to
access the same identity map. By design, the identity_map plugin stores
the hash in a thread-local variable, so other threads cannot access the
information. If you know what you are doing, it's not a difficult change
to make a thread-safe global hash, but if you really know what you are
doing, you will not attempt to do so. While most of Sequel is thread-safe
(Database, Dataset, Model class), Model instances are not thread safe, so
concurrent access to Model instances by multiple threads is specifically
unsupported.
Psuedo-code:
>
> class Thing < RCTETreeEnabledNode
> def non_persistent_stuff
> @non_persistent_stuff ||= Array.new
> end
> end
>
> def routine1
> a = Thing[1]
> b = Thing[2]
> c = Thing[3] # Marshals an entity to an Object instance
> with .object_id = 2050, let's say.
>
> b.non_persistent_stuff << c
>
> a.add_child c
>
> puts "Parent relationship was previously established." if b.parent
> == a
> # => Parent relationship was previously established.
> end
>
> def routine2
> a = Thing[1]
> c = Thing[3]) # Shouldn't this return a reference to
> Object.object_id = 2050?
>
> puts a.children.include? c # => true
>
> z = a.children.select { |child| child.non_persistent_stuff.include?
> c }
>
> puts "Is this a problem? That z is empty?" if z.empty?
> end
>
> My guess is that my design is simply wrong, and I should be doing this
> another way.
>
You don't show multiple threads operating here, so I'm not sure if my
description above applies to you. If I'm not understanding your
description correctly, it would probably help if you could come up with a
completely self-contained example.
Based on your current example, I would recommend looking into using Redis
to store the non-persistent stuff.
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/sequel-talk/-/XzGkbYnGQ64J.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en.