Search |
||
Grizzly : Speedup the ProtocolFilter response timePosted by survivant on November 21, 2008 at 12:51 PM PST
Suppose that you are dealing with sql query that you send to a database. Some query could take few seconds to run, that will block a Thread. Even if you have few Threads in your pool, they could all be stuck there too. To avoid that you can use the Producer/Consumer pattern.
Take a look at this snippets. .... // default Pipeline settings Pipeline pipeline = new DefaultPipeline(); pipeline.setMaxThreads(5); controller.setPipeline(pipeline); // the ParserProtocolFilter that will parse the query QuoteQueryProtocolFilter protocolParser = new QuoteQueryProtocolFilter(); // the ProtocolFilter that will process the query QuoteQueryManagerFilter quoteManagerFilter = new QuoteQueryManagerFilter(); final ProtocolChain protocolChain = new DefaultProtocolChain(); protocolChain.addFilter(protocolParser); protocolChain.addFilter(quoteManagerFilter); .... Suppose we want to simulate a waiting IO, you can do a sleep for 30 seconds. The effect will be that the manager will wait public class QuoteQueryManagerFilter implements ProtocolFilter { public boolean execute(Context context) throws IOException { String query = (String) context.removeAttribute(ProtocolParser.MESSAGE); ...... // that will simulate that the database take 30 sec to complete the query try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } // call the database //databaseManager.execute(query); return true; } If you send 10 query to your application, the application will block after 5 query (pipeline threads). The 6th query will be executed after 30 sec. We can change that behaviour easily. We will need a Producer and a Consumer with a queue. You can take a LinkedBlockingQueue as a queue. Here the snippets for the Consumer : (the Thread.sleep is only for testing) public class Consumer implements IConsumer, Runnable { protected BlockingQueue<String> blockingQueue; .... public void run(){ ..... while(!Thread.currentThread().isInterrupted()){ try { String query = blockingQueue.take(); System.out.println(" took item=" + query); // now call your database // that will simulate that the database take 30 sec to complete try { Thread.sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } databaseManager.process(command); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } ..... } For the Producer, I use my databaseManager. public class DatabaseManager { protected BlockingQueue<QueueCommand> blockingQueue; .... public void init(){ ThreadGroup tg = new ThreadGroup("Producer/Consumer"); quoteConsumer = new QuoteConsumer(this, blockingQueue); new Thread(tg, quoteConsumer,"QuoteConsumer").start(); } public void addtoQueue(String query) { System.out.println("add item=" + query); blockingQueue.add(query); } .... } and don't forget the change the QuoteQueryManagerFilter : public boolean execute(Context context) throws IOException { String query = (String) context.removeAttribute(ProtocolParser.MESSAGE); ...... // call the database databaseManager.addToQueue(query); return true; } If you try this, the database will still take 30 seconds to run, but your application will be able to handle the requests. »
Related Topics >>
Open Source Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|