Skip to content

Make GenerateQuery's query message thread-local - #254

Open
piyush15102003 wants to merge 1 commit into
intuit:developfrom
piyush15102003:fix/generatequery-thread-safety
Open

piyush15102003 wants to merge 1 commit into
intuit:developfrom
piyush15102003:fix/generatequery-thread-safety

Conversation

@piyush15102003

Copy link
Copy Markdown

Make GenerateQuery's query message thread-local

Fixes #223

Problem

GenerateQuery stores the QueryMessage it is building in a single private static field. select() resets that field and then writes into it, so two threads building queries at the same time overwrite each other's message. I reproduced this with 8 threads: on the very first iteration, one thread's query came back as

SELECT StringData FROM Data WHERE StringData = 'thread3-0' AND StringData = 'thread5-0' AND ... AND StringData = 'thread0-0'

which includes the WHERE clauses of 7 different threads. Anyone using the SDK in a multi-threaded server (a web app, or a worker pool syncing several companies) can send corrupted queries this way.

Fix

The message is now held in a ThreadLocal<QueryMessage>, the same approach this class already uses for path. The public getMessage() / setMessage() / resetQueryMessage() methods keep their signatures, so existing callers are unaffected.

Testing

  • Added GenerateQueryConcurrencyTest: 8 threads start together on a CyclicBarrier, and each builds 500 queries with thread-specific values and checks the generated string.
  • Without the fix the test fails on the first iteration. With the fix, all 21 tests in com.intuit.ipp.query pass, and I ran them 3 times to check for flakiness.

Command: mvn -pl ipp-v3-java-devkit -am test -Dtest="com.intuit.ipp.query.*Test" -Dsurefire.failIfNoSpecifiedTests=false

GenerateQuery kept the QueryMessage being built in a single static
field, so threads building queries at the same time reset and wrote
into each other's message. One thread's query could come back with
WHERE clauses from several other threads.

Store the message in a ThreadLocal, the same way the path field
already is, and add a test that builds queries from 8 threads at once.

Fixes intuit#223
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GenerateQuery is not suitable for multi-threaded environments

1 participant