• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Data class multithreaded load test (UB1.1.2)

 
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll share with you a multithreaded load test which I just finished writing.
It is designed to run random create/read/update/delete/finds on a UrlyBird database and Sysouts everything. It also performs at the end a small test that the database is still valid.

It uses plain JUnit, but you can probably transform it pretty easy in a main() class if you want. (JUnit is used for setUp and running, not really performing any asserts with it).

Every lock/do-something/unlock sequence is performed by three separate threads, so if you're using a 3-tier architecture (which does this sequences in a single thread) but don't know if the Data can manage separate calls from 3 threads - you can use this test.

I for one decided to use a 3-tier architecture. However, I wanted my Data class to be ready to work in a 2-tier "mode" because I suspect that the automated tests used for grading our projects want it this way.

Of course, if you're using a 2-tier, than passing this kind of test is a must.

A big advantage over the already existing tests around here is that it has Javadoc .

Here they are (it's made of two classes):






If you use these test, please come back here with opinions about it and improvements. Thanks.
 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Alecsandru,
Program looks interesting. If I may offer some input. The programs appears to be overloaded with many condition statements determining Mode. You may what to study a good Design Patterns book and focus your attention on the State Pattern. You will discover that so many of your condition statements and case logic can be implemented more effectively (removed) and much of the redundant code eliminated. The "run" methods need to be placed in Runnables. This should make your code more readable and maintainable.
 
Alecsandru Cocarla
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, you're right. I could use a State pattern and I think I 'll do it . Thanks.
 
Alecsandru Cocarla
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, so here's the new version.

What's new:
- More classes
- Improved design
- Improved logging
- Not all the states were converted to new ThreadSequence implementations, because that would be (in my opinion) over-engineering in this case.
- I could not use Runnable for the SequenceStep because I need to access both join() and internal state within other threads.









A short user guide:
1. Run the test
2. Investigate the output. You should:
- not have a message like "TSxxx locked AA" unless another TS already issued the "TSyyy unlocked AA" (except the first lock, of course). An amendment - there are cases when concurrent writing to sysout will mess up the order of these two outputs. If they are close (like one after the other but in the wrong order, and this only happens once in a while, then you're probably safe. However, you should also check your logs and see what exactly happened.
- not have messages like "TSxxx read/updated/deleted AA" after another TS deleted the same record (unless you reuse deleted records and some other TS already created a new record in the same place).

Have fun with it and come back with feedback

[ November 01, 2008: Message edited by: Alecsandru Cocarla ]
[ November 01, 2008: Message edited by: Alecsandru Cocarla ]
 
Alecsandru Cocarla
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
User guide continued...
How to disambiguate when the amendment at point 2 mentioned before happens.

This a sample of an ambiguous output that I received:
TS049 unlocking 14 - here it starts
TS158 unlocked 33
TS156 locked 12
TS156 deleting 12
TS044 unlocked 34
TS241 locked 16
TS241 updating 16
TS046 unlocked 20
TS132 locked 34
TS132 updating 34
TS016 deleted 43
TS016 unlocking 43
TS100 locked 20
TS100 deleting 20
TS082 locked 14 - another TS locked my record? It's not unlocked yet
TS082 deleting 14 - what??? It even deleted it
TS055 updated 22
TS055 unlocking 22
TS049 unlocked 14 - S**t, that's a little too late!!

What I did - I added sysouts in my locking code (immediately after recordLock.lock() and right before recordLock.unlock(), in order to see what exactly what happened.

This is what happened in fact:

TS049 unlocking 14 - here it starts
----unlocking 34
----unlocked 34
TS158 unlocked 33
----locked 12
----locked 16
TS156 locked 12
TS156 deleting 12
TS044 unlocked 34
----unlocking 20
----unlocked 20
----locked 34
TS241 locked 16
TS241 updating 16
----locked 20
----unlocking 14 - very well
----unlocked 14 - now it's unlocked
TS046 unlocked 20
TS132 locked 34
TS132 updating 34
TS016 deleted 43
TS016 unlocking 43
TS100 locked 20
----locked 14 - it's already unlocked, so it can lock
TS100 deleting 20
TS082 locked 14 - it's already unlocked, so it can lock
TS082 deleting 14 - it's locked, can delete
TS055 updated 22
TS055 unlocking 22
TS049 unlocked 14 - the output is late, but the sysouts from locking methods really showed me what went on.
[ November 21, 2008: Message edited by: Alecsandru Cocarla ]
 
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Alesc,
I have 2 questions.

1. The conditions, you use in the constructors for Lockless and Lockable Thread Sequences.



I think the the conditional operator should be 'OR' instead of 'AND'

2. Why do you exclude the CREATE_MODE from the Lockable sequence? I expect that creating a new record entails
a) Obtaining a write lock on the database.
b) Writing to the database.
c) Releasing the write lock.

Thanks.
 
Alecsandru Cocarla
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Fola Fadairo:

1. The conditions, you use in the constructors for Lockless and Lockable Thread Sequences.


I think the the conditional operator should be 'OR' instead of 'AND'


The != sign makes the difference. So, if the mode is not one of the expected ones, an exception is thrown.
You can run the tests, and you'll see it works.

Originally posted by Fola Fadairo:

2. Why do you exclude the CREATE_MODE from the Lockable sequence? I expect that creating a new record entails
a) Obtaining a write lock on the database.
b) Writing to the database.
c) Releasing the write lock.


My create() method signature from the SUN provided interface is:

public int create(String[] data) throws DuplicateKeyException;

No cookie involved for create. This means no lock is required either. Also, no record number is involved, which means I wouldn't know what record to lock. Only update() and delete() require locking. And this is ok, because the only thing you can do with a "creatable" (meaning already deleted or non-existent yet) record is to create() (you can't delete, update or read where a record should be created). After a record is created, no other create() operation can occur in the same place, unless you first delete the record. In conclusion, there's no way two clients create the same record at the same time, or one thread read/delete/update while some other thread is creating.
 
reply
    Bookmark Topic Watch Topic
  • New Topic