/*
 *   Copyright 2009 Joubin Houshyar
 * 
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *    
 *   http://www.apache.org/licenses/LICENSE-2.0
 *    
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package org.jredis.examples;

import static org.jredis.ri.alphazero.support.DefaultCodec.toLong;
import static org.jredis.ri.alphazero.support.DefaultCodec.toStr;
import java.util.Random;
import org.jredis.JRedisFuture;
import org.jredis.RedisException;
import org.jredis.connector.ConnectionSpec;
import org.jredis.ri.alphazero.JRedisPipeline;
import org.jredis.ri.alphazero.connection.DefaultConnectionSpec;
import org.jredis.ri.alphazero.support.Log;

/**
 * Extension of {@link UsingJRedisFuture} with a {@link JRedisPipeline} as the 
 * provider.  
 * <p>See {@link UsingJRedisFuture} for demonstration of generic asynchronous
 * semantics.
 * <p>See {@link UsingJRedisPipeline#exampleUseofSyncInPipeline(ConnectionSpec)} for {@link JRedisPipeline} specific
 * mix mode usage incorporating asynchronous and synchronous calls.
 *  
 * 
 * @author  Joubin Houshyar (alphazero@sensesay.net)
 * @version alpha.0, Oct 11, 2009
 * @since   alpha.0
 * @see UsingJRedisFuture
 * 
 */

public class UsingJRedisPipeline extends UsingJRedisFuture {

	public static void main (String[] args) {
		final int database = 13;
		ConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec("localhost", 6379, database, "jredis".getBytes());
		
	    exampleUseofSyncInPipeline(connectionSpec);
    }
	/**
	 * Example highlights usage pattern of pipeline with both the natural asynchronous
	 * semantics and synchronous semantics provided by {@link JRedisPipeline#sync()}
	 * 
     * @param connectionSpec
     */
    @SuppressWarnings("boxing")
	private static void exampleUseofSyncInPipeline (ConnectionSpec connectionSpec) {
    	
    	// Note that we are using a JRedisPipeline reference and not a generic
    	// JRedisFuture here -- this exposes the additional 
    	
    	JRedisPipeline pipeline = new JRedisPipeline(connectionSpec);
    	
    	/*
    	 * Alright, so a hokey example of situations where we would like to
    	 * asynchronously pipeline a bunch of commands, and then at various point in
    	 * the process need to sync up with redis and get values before continuing.
    	 * 
    	 * Obviously we can do this using JRedisFuture as well by calling get() on the
    	 * returned Future object, but the sync() method may be enhanced in future to
    	 * provide additional features.  Regardless, it does some of the boiler plate
    	 * ExecutionException handling code so its a bit prettier.
    	 */
    	try {
    		long start = System.currentTimeMillis();
    		
    		/* a sequence of asynchronous calls */
    		
	        pipeline.ping();
	        pipeline.flushdb();

	        Random rand = new Random();
	        byte[] data = new byte[8];
	        for(int i=0; i<100000; i++){
	        	rand.nextBytes(data);
	        	pipeline.lpush("my-list", data);
	        }
	        /* 
	         * switch to synchronous semantics
	         * the following call will block until
	         * all the responses for above + the llen() 
	         * itself have been received.
	         */
	        
	        long llen = pipeline.sync().llen("my-list");
	        
	        String cntrKey = "my-cntr";
	        for(int i=0; i<100000; i++) {
	        	pipeline.incr(cntrKey);
	        }
	        /* sync call */
	        long cntr = toLong (pipeline.sync().get(cntrKey));
	        
	        for(int i=0; i<100000; i++){
	        	pipeline.set("random:"+i, "value:" + rand.nextInt());
	        }
	        /* sync call */
	        String randomVal = toStr (pipeline.sync().get("random:"+999));
	        
	        pipeline.flushdb();
    		System.out.format ("end using sync() = %d msec\n", System.currentTimeMillis() - start);
	        
	        System.out.format("%s => %d\n", cntrKey, cntr);
	        System.out.format("%s => %s\n", "random:"+999, randomVal);
	        System.out.format("%s has %s items\n", "my-list", llen);
	        
        }
        catch (RedisException e) {
        	Log.problem("RedisException: " + e);
        }
        finally{
        	pipeline.sync().quit();
        	Log.log("shutting down.");
        }
    }
	/**
     * @param connectionSpec
     */
    public UsingJRedisPipeline (ConnectionSpec connectionSpec) {
	    super(connectionSpec);
    }

	/* (non-Javadoc)
	 * @see org.jredis.examples.UsingJRedisFuture#getProviderInstance(org.jredis.connector.ConnectionSpec)
	 */
	@Override
	protected JRedisFuture getProviderInstance (ConnectionSpec connectionSpec) {
		return new JRedisPipeline(connectionSpec);
	}
}

@@ -3295,32 +3295,33 @@
 nt i=0; i%3C100000
+0
 ; i++)%7B%0A%09       

Update the usage example -- ADHOC TESTED