| 
 | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||
java.lang.Objectcom.almworks.sqlite4java.SQLiteQueue
public class SQLiteQueue
SQLiteQueue is a basic implementation of job queue for an SQLite connection. It provides multi-threaded
 or GUI application with asynchronous execution of database tasks in a single separate thread with a single
 SQLiteConnection.
 
start() and stop(boolean) methods correspondingly.
 Each database task is represented by a subclass of SQLiteJob. A task is scheduled for execution
 by execute(J) method. Tasks are served on first-come, first-serve basis.
 
 Public methods of SQLiteQueue are thread-safe, unless noted otherwise.
 
 When writing tasks, it's a good practice to keep transaction boundaries within single task. That is, if you
 BEGIN TRANSACTION in the task, make sure you COMMIT or ROLLBACK in the end. Otherwise, your transaction will
 remain unfinished, locks held, and you possible wouldn't know which job will execute next in the context of
 this unfinished transaction.
 
 SQLiteQueue may be subclassed in order to change certain behavior. If you need some things to be done
 differently, look for a protected method to override. For example, you can implement a priority queue
 instead of FIFO queue.
 
 SQLiteQueue and SQLiteJob are written to handle exceptions and errors in a controlled way. In particular,
 if the queue thread terminates abnormally, SQLiteQueue will try to "reincarnate" by starting another thread
 and opening another connection to the database. All queued tasks (except for the one that caused the problem)
 should survive the reincarnation and execute in the new thread.
 
 Reincarnation is not possible for in-memory database, since the database is lost after connection closes.
 
 Some examples:
 
 void start() {
   myQueue = new SQLiteQueue(myDatabaseFile);
   myQueue.start();
 }
 
 int getTableRowCount(final String tableName) {
   return myQueue.execute(new SQLiteJob<Integer>() {
     protected Integer job(SQLiteConnection connection) throws SQLiteException {
       SQLiteStatement st = connection.prepare("SELECT COUNT(*) FROM " + tableName);
       try {
         st.step();
         return st.columnInt(0);
       } finally {
         st.dispose();
       }
     }
   }).complete();
 }
 
SQLiteJob| Field Summary | |
|---|---|
| static long | DEFAULT_REINCARNATE_TIMEOUTDefault timeout for reincarnating database thread. | 
| protected  java.util.Collection<SQLiteJob> | myJobsStores queued jobs. | 
| Constructor Summary | |
|---|---|
| SQLiteQueue()Constructs the queue, which will use an in-memory database. | |
| SQLiteQueue(java.io.File databaseFile)Constructs the queue. | |
| SQLiteQueue(java.io.File databaseFile,
            java.util.concurrent.ThreadFactory threadFactory)Constructs the queue and allows to specify a factory for the queue thread. | |
| Method Summary | ||
|---|---|---|
| protected  void | addJob(SQLiteJob job)Adds a job to the job collection. | |
| protected  void | afterExecute(SQLiteJob job)Do some work after job.execute() finished. | |
| protected  java.util.Collection<SQLiteJob> | createJobCollection()Creates a new collection for storing pending jobs. | |
| protected  void | disposeConnection(SQLiteConnection connection)Disposes the connection. | |
| 
 | execute(J job)Places a job in the queue for asynchronous execution in database thread. | |
| protected  void | executeJob(SQLiteJob job)Runs the job with the current connection. | |
|  SQLiteQueue | flush()Waits until all jobs in the queue are executed. | |
|  java.io.File | getDatabaseFile()Get the underlying database file. | |
| protected  long | getReincarnationTimeout()Provides reincarnation timeout (the period to wait before reincarnating abnormally stopped queue thread). | |
| protected  void | handleJobException(SQLiteJob job,
                   java.lang.Throwable e)Do some work if job threw an exception. | |
| protected  void | initConnection(SQLiteConnection connection)Initialize a new connection. | |
|  boolean | isDatabaseThread()Checks if the current thread is the thread that runs the queue's database connection. | |
| protected  boolean | isJobQueueEmpty()Checks if there are no more pending jobs. | |
| protected  boolean | isReincarnationPossible()Checks if reincarnation should be attempted after queue thread terminates abnormally. | |
|  boolean | isStopped()Checks if the queue is stopped. | |
|  SQLiteQueue | join()Waits for the queue to stop. | |
| protected  SQLiteConnection | openConnection()Creates and opens a connection to the database. | |
| protected  void | reincarnate(long reincarnateTimeout)Reincarnates the queue. | |
| protected  java.util.List<SQLiteJob> | removeJobsClearQueue()Clears the queue and returned removed jobs. | |
| protected  void | rollback()Rolls back current transaction. | |
| protected  SQLiteJob | selectJob()Selects the next job from pending jobs to be executed. | |
|  SQLiteQueue | start()Starts the queue by creating a new thread, opening connection in that thread and executing all jobs there. | |
|  SQLiteQueue | stop(boolean gracefully)Stops the queue. | |
|  java.lang.String | toString() | |
| Methods inherited from class java.lang.Object | 
|---|
| clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait | 
| Field Detail | 
|---|
public static final long DEFAULT_REINCARNATE_TIMEOUT
protected java.util.Collection<SQLiteJob> myJobs
| Constructor Detail | 
|---|
public SQLiteQueue()
start()public SQLiteQueue(java.io.File databaseFile)
SQLiteConnection.open(boolean) method to create a connection within
 queue thread.
 
 The queue must be started in order for jobs to be executed.
databaseFile - database file to connect to, or null to open an in-memory databasestart()
public SQLiteQueue(java.io.File databaseFile,
                   java.util.concurrent.ThreadFactory threadFactory)
databaseFile - database file to connect to, or null to open an in-memory databasethreadFactory - the factory for thread(s), cannot be null| Method Detail | 
|---|
public java.lang.String toString()
toString in class java.lang.Objectpublic java.io.File getDatabaseFile()
public SQLiteQueue start()
stop(boolean) method is called, or until it is terminated by non-recoverable error.
 
 Calling this method second time does not have any effect. A queue cannot be started after it has stopped.
 
 Any jobs added to the queue prior to start() will be carried out.
 
 This method is thread-safe: it may be called from any thread.
java.lang.IllegalStateException - if threadFactory failed to produce a new threadpublic SQLiteQueue stop(boolean gracefully)
execute(J) method. The thread
 and connection are finished and disposed.
 
 If gracefully parameter is true, the currently queued jobs will be executed before queue stops.
 Otherwise, any pending jobs are cancelled, and the currently running job may be cancelled to. (If the currently
 running job is ignorant of job.isCancelled() status and does not run a long SQL statement, it still may finish
 normally.)
 
 After call to stop(true) you can call stop(false) to force non-gracefull shutdown.
 Other than that, calling stop() second time has no effect.
 
 If the queue hasn't been started, it will not be able to start later.
 
 This method is thread-safe: it may be called from any thread. It finishes immediately, while actual stopping
 of the queue happening asynchronously. If you need to wait until queue is fully stopped, use join() method
 after you called stop().
gracefully - if true, jobs already queued will be executed, then the queue will stop
public SQLiteQueue join()
                 throws java.lang.InterruptedException
Thread.join(long) method to join with the queue thread.
 
 Note that this method does not stop the queue. You need to call stop(boolean) explicitly.
 
 If queue has not been started, the method returns immediately.
java.lang.InterruptedException - if the current thread is interrupted
java.lang.IllegalStateException - if called from the queue threadpublic <T,J extends SQLiteJob<T>> J execute(J job)
SQLiteJob.job(com.almworks.sqlite4java.SQLiteConnection) method will be called from the database thread with an instance of
 SQLiteConnection. Job may provide a return value, which will be treated as the job result.
 
 The queue must be started in order for jobs to start executing. Jobs may be added to the queue before or after
 the queue is started. However, if the queue is already stopped, the job will be immediately cancelled. (It will
 receive SQLiteJob.jobCancelled() and SQLiteJob.jobFinished(T) callbacks before this method finishes.)
 
 Because this method returns the argument, you can chain this method with other methods in SQLiteJob or in its
 subclass:
 
   MyResult r = myQueue.execute(new SQLiteJob<MyResult>() { ... }).complete();
 
T - class of the job's result; use Object or Void if no result is neededJ - job classjob - the job to be executed on this queue's database connection, must not be null
SQLiteJob
public SQLiteQueue flush()
                  throws java.lang.InterruptedException
java.lang.InterruptedException - if the current thread is interruptedpublic boolean isStopped()
public boolean isDatabaseThread()
protected void addJob(SQLiteJob job)
job - the job to be added to myJobs, the latter possible being nullprotected java.util.Collection<SQLiteJob> createJobCollection()
protected boolean isJobQueueEmpty()
protected java.util.List<SQLiteJob> removeJobsClearQueue()
isJobQueueEmpty() must return true.
 
 This method is called under synchronized lock and must not call any listeners or alien code.
protected SQLiteJob selectJob()
protected SQLiteConnection openConnection()
                                   throws SQLiteException
SQLiteException - if connection cannot be createdinitConnection(com.almworks.sqlite4java.SQLiteConnection)
protected void initConnection(SQLiteConnection connection)
                       throws SQLiteException
connection - freshly opened database connection
SQLiteException - if any initialization code failsprotected void disposeConnection(SQLiteConnection connection)
connection - database connection no longer in use by the queueprotected void rollback()
protected void executeJob(SQLiteJob job)
                   throws java.lang.Throwable
job - next job from the queue
java.lang.Throwable - any kind of problem
protected void afterExecute(SQLiteJob job)
                     throws java.lang.Throwable
job - finished job
java.lang.Throwable - any kind of problem
protected void handleJobException(SQLiteJob job,
                                  java.lang.Throwable e)
                           throws java.lang.Throwable
job - erred jobe - exception thrown by the job
java.lang.Throwable - any kind of problemprotected long getReincarnationTimeout()
protected boolean isReincarnationPossible()
protected void reincarnate(long reincarnateTimeout)
reincarnateTimeout - time to wait| 
 | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||