Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Rel concurrency issue proving test cases #1704

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def delete_all_rels
def replace_with(node_or_nodes)
node_or_nodes = Array(node_or_nodes).map { |arg| arg.is_a?(ActiveGraph::Node) ? arg : @model.find(arg) }
original_ids = self.pluck(:id)
$concurrency_queue << 'ready' if $concurrency_test # completed read above so send signal in the queue
while $concurrency_test && $concurrency_test_wait # wait till other thread has also completed its read
sleep 1
end
delete_rels_for_nodes(original_ids, node_or_nodes.collect(&:id))
add_rels(node_or_nodes, original_ids)
end
Expand Down
53 changes: 53 additions & 0 deletions spec/e2e/relationship/persistence/query_factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,59 @@ def self.count
expect(from_node.reload.to_classes).to be_empty
end

it 'does not create duplicate has_one relationship' do
from_node.save
to_node.save
begin
$concurrency_test = true
$concurrency_queue = Queue.new
$concurrency_test_wait = true
t1 = Thread.new { to_node.update(from_class: from_node) }
t2 = Thread.new { to_node.update(from_class: from_node) }
while $concurrency_queue.size < 2
# wait till both thread have complted read query
sleep 1
end
$concurrency_test_wait = false # make threads resume their work
[t1, t2].join # wait for the threads to finish

# to_node.from_class only returns 1 result but in db there are two rels associated with this node
# this assertion fails with with result 2 proving the presence of bug
expect(ActiveGraph::Base.query("MATCH (node2:`ToClass`)<-[rel1:`HAS_REL`]-(from_class:`FromClass`) return from_class").to_a.size).to eq(1)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot of the data
Screenshot 2023-11-30 at 8 09 28 PM

ensure
$concurrency_test = nil
$concurrency_test_wait = nil
$concurrency_queue = nil
end
end

it 'does not create two rels with different nodes in has_one relationship' do
from_node.save
to_node.save
from_node_two = FromClass.create(name: 'foo-2')
begin
$concurrency_test = true
$concurrency_queue = Queue.new
$concurrency_test_wait = true
t1 = Thread.new { to_node.update(from_class: from_node) }
t2 = Thread.new { to_node.update(from_class: from_node_two) }
while $concurrency_queue.size < 2
# wait till both thread have complted read query
sleep 1
end
$concurrency_test_wait = false # make threads resume their work
[t1, t2].join # wait for the threads to finish

# to_node.from_class only returns 1 result but in db there are two rels associated with this node
# this assertion fails with with result 2 proving the presence of bug
expect(ActiveGraph::Base.query("MATCH (node2:`ToClass`)<-[rel1:`HAS_REL`]-(from_class:`FromClass`) return from_class").to_a.size).to eq(1)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot of the data
Screenshot 2023-11-30 at 8 10 19 PM

ensure
$concurrency_test = nil
$concurrency_test_wait = nil
$concurrency_queue = nil
end
end

it 'delets has_one rel from from_node when new relation is created' do
to_node_two = ToClass.new(name: 'bar-2')
Rel2Class.new(from_node: from_node, to_node: to_node, score: 10).save
Expand Down
Loading