Author: greg

  • Creating Javascript accessible object from C++ / CEF

    Example with Chromium Embedded Framework (CEF) on how to create an object in C++ and make it accessible via Javascript.

    console.inof(api)
    Object {ready: true, version: "psql.0.0.1", info: Object, getVersion: function}
    
    void ExtractEngineApp::OnContextCreated(
    	CefRefPtr browser, 
    	CefRefPtr frame, 
    	CefRefPtr context)
    {
    
    	auto info = CefV8Value::CreateObject(NULL, NULL);
    	info->SetValue("major", CefV8Value::CreateString("0"), V8_PROPERTY_ATTRIBUTE_READONLY);
    	info->SetValue("minor", CefV8Value::CreateString("1"), V8_PROPERTY_ATTRIBUTE_READONLY);
    	
    	auto global = context->GetGlobal();
    	auto api = CefV8Value::CreateObject(NULL, NULL);
    
    	global->SetValue("api", api, V8_PROPERTY_ATTRIBUTE_NONE);
    
    	auto fun = CefV8Value::CreateFunction("getVersion", new engine:: PhantomExtensionHandler(this));
    	api->SetValue("getVersion", fun, V8_PROPERTY_ATTRIBUTE_NONE);
    	
    	// Readonly properties
    	api->SetValue("ready", CefV8Value::CreateBool(true), V8_PROPERTY_ATTRIBUTE_READONLY);
    	api->SetValue("version", CefV8Value::CreateString("psql.0.0.1"), V8_PROPERTY_ATTRIBUTE_READONLY);
    
    	// Readonly Object access
    	api->SetValue("info", info, V8_PROPERTY_ATTRIBUTE_READONLY);
    }
    
    
    class PhantomExtensionHandler : public CefV8Handler
    	{
    	public:
    		explicit PhantomExtensionHandler(CefRefPtr client_app)
    			: client_app(client_app)
    			, messageId(0)
    		{
    
    		}
    
    		virtual bool Execute(const CefString& name,
    			CefRefPtr object,
    			const CefV8ValueList& arguments,
    			CefRefPtr& retval,
    			CefString& exception)
    		{
    			if (name == "getVersion")
    			{
    				retval = CefV8Value::CreateString("Version(SemVer) # 0.0.1");
    			}
    
    			return true;
    		}
    
    	private:
    		CefRefPtr client_app;
    		int32 messageId;
    
    		IMPLEMENT_REFCOUNTING(PhantomExtensionHandler);
    	};
    
  • Recursively GREP for specific content

    nohup  egrep -rnw '=\s112'  --include=*.java ./ 2>&1 | tee ~/112-audit-nick.txt
    
  • Data retrieval service with exponential backoff

    Here we will create Data retrieval service with exponential backoff that we covered in the previous post.

    Implementation

    
    package com.rms.blueprint.data;
    
    import java.util.Date;
    import java.util.Objects;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Function;
    import java.util.function.ObjLongConsumer;
    import java.util.function.Supplier;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class DataRetrievalWithBackoff implements Runnable
    {
        public final Logger LOGGER = LoggerFactory.getLogger(DataRetrievalWithBackoff.class);
    
        private final Supplier pendingSupplier;
    
        private final ObjLongConsumer readyConsumer;
    
        private final Function capacitySupplier;
    
        private final long minLoadDurationInSeconds;
    
        private final long capacity;
    
        private final long maxBackoffDelayInSeconds;
    
        /**
         * @param config
         *            Configuration properties
         * @param pendingSupplier
         *            Supplier that tells us how many items is being processed at
         *            this time
         * @param readyConsumer
         *            Consumer that will be called when data is ready to load
         * @param capacitySupplier
         *            Function to calculate current capacity
         */
        private DataRetrievalWithBackoff(final long capacity, final long minLoadDurationInSeconds,
                final long maxBackoffDelayInSeconds, final Supplier pendingSupplier,
                final ObjLongConsumer readyConsumer, final Function capacitySupplier)
        {
            Objects.requireNonNull(pendingSupplier);
            Objects.requireNonNull(readyConsumer);
            Objects.requireNonNull(capacitySupplier);
    
            this.capacity = capacity;
            this.minLoadDurationInSeconds = minLoadDurationInSeconds;
            this.maxBackoffDelayInSeconds = maxBackoffDelayInSeconds;
    
            this.pendingSupplier = pendingSupplier;
            this.readyConsumer = readyConsumer;
            this.capacitySupplier = capacitySupplier;
    
            LOGGER.info(String.format("capacity ", capacity));
            LOGGER.info(String.format("minLoadDurationInSeconds ", minLoadDurationInSeconds));
            LOGGER.info(String.format("maxBackoffDelayInSeconds ", maxBackoffDelayInSeconds));
    
        }
    
        @Override
        public void run()
        {
            LOGGER.info("Running Data Retrieval");
    
            long lastLoadedTime = 0l;
            int attempt = 0;
    
            while (true)
            {
                if (Thread.currentThread().isInterrupted())
                {
                    LOGGER.trace("Interrupted stopping [while]");
                    break;
                }
    
                final long delta = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - lastLoadedTime);
                final long pending = pendingSupplier.get();
    
                final long backoffTime = DataUtil.backoff(attempt,
                                                          maxBackoffDelayInSeconds,
                                                          minLoadDurationInSeconds / 2.0);
    
                LOGGER.trace("Loading : lastLoaded : {} > {}  delta(s) {} pending : {} backoffTime  = {}",
                             new Object[] { lastLoadedTime, new Date(lastLoadedTime), delta, pending, backoffTime });
    
                if (delta >= minLoadDurationInSeconds && pending <= capacitySupplier.apply(capacity))
                {
                    LOGGER.info("Loading : lastLoaded :  {} >  {}  delta(s) {} pending : {}",
                                new Object[] { lastLoadedTime, new Date(lastLoadedTime), delta, pending });
    
                    // let the consumer know that we are ready
                    readyConsumer.accept(backoffTime, attempt);
    
                    if (pending == 0)
                        ++attempt;
                    else
                        attempt = 0;
    
                    lastLoadedTime = System.currentTimeMillis();
                }
                else
                {
                    ++attempt;
                }
    
                try
                {
    
                    Thread.sleep(TimeUnit.SECONDS.toMillis(backoffTime));
                }
                catch (final InterruptedException e)
                {
                    LOGGER.trace("Interrupted stopping  [sleep]");
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
    
        public static class Builder
        {
            private final Function DEFAULT_CAPACITY_SUPPLIER = (capacity) -> capacity / 2;
    
            private long minLoadDurationInSeconds = 60;
    
            private long capacity = 100;
    
            private long maxBackoffDelayInSeconds = 120;
    
            private Supplier pendingSupplier;
    
            private ObjLongConsumer readyConsumer;
    
            private Function capacitySupplier;
    
            public Builder capacity(final long capacity)
            {
                this.capacity = capacity;
                return this;
            }
    
            public Builder maxBackoffDelay(final long duration, final TimeUnit unit)
            {
                Objects.requireNonNull(unit);
                this.maxBackoffDelayInSeconds = unit.toSeconds(duration);
                return this;
            }
    
            public Builder minLoadDuration(final long duration, final TimeUnit unit)
            {
                Objects.requireNonNull(unit);
                this.minLoadDurationInSeconds = unit.toSeconds(duration);
                return this;
            }
    
            public Builder readyConsumer(final ObjLongConsumer readyConsumer)
            {
                Objects.requireNonNull(readyConsumer);
                this.readyConsumer = readyConsumer;
                return this;
            }
    
            public Builder capacitySupplier(final Function capacitySupplier)
            {
                Objects.requireNonNull(capacitySupplier);
                this.capacitySupplier = capacitySupplier;
                return this;
            }
    
            public Builder pendingSupplier(final Supplier pendingSupplier)
            {
                Objects.requireNonNull(capacitySupplier);
                this.pendingSupplier = pendingSupplier;
                return this;
            }
    
            public DataRetrievalWithBackoff build()
            {
                // check invariant
                Objects.requireNonNull(pendingSupplier, "Pening items supplier not provided");
                Objects.requireNonNull(readyConsumer, "Ready Consumer not provided");
    
                if (capacitySupplier == null)
                    capacitySupplier = DEFAULT_CAPACITY_SUPPLIER;
    
                return new DataRetrievalWithBackoff(capacity,
                                                    minLoadDurationInSeconds,
                                                    maxBackoffDelayInSeconds,
                                                    pendingSupplier,
                                                    readyConsumer,
                                                    capacitySupplier == null ? DEFAULT_CAPACITY_SUPPLIER
                                                        : capacitySupplier);
            }
        }
    }
    
    
    

    Usage

    
       //@formatter:off
                final DataRetrievalWithBackoff service = new DataRetrievalWithBackoff.Builder()
                        .capacity(1000)
                        .maxBackoffDelay(100, TimeUnit.SECONDS)
                        .minLoadDuration(10, TimeUnit.SECONDS)
                        .pendingSupplier(() -> getNumberOfPendingItemsToProcess())
                        .readyConsumer((time, attempt) -> fire(new DataLoadEvent()))
                    .build(); 
               //@formatter:on
    
  • Exponential backoff

    In a variety of computer networks, binary exponential backoff or truncated binary exponential backoff refers to an algorithm used to space out repeated retransmissions of the same block of data, often as part of network congestion avoidance.

    Wikipedia Exponential backoff

    Here is an implementation in Java

        /**
         * Calculate Exponential backoff
         * 
         * @param attempt
         *            number that we are checking
         * @param maxDelayInSeconds
         *            Max amount of time to wait
         * @param multiplier
         *            How much of backoff to perform
         * @return
         */
        public static long backoff(final int attempt, final long maxDelayInSeconds, final double multiplier)
        {
            final double delayInSec = (Math.pow(2.0, attempt) - 1.0) * .5;
            return Math.round(Math.min(delayInSec * multiplier, maxDelayInSeconds));
        }  
    

    Example

    Here we have exponential backoff defined with three different parameters for the muliplier and 120 seconds as the max time.

    
    System.out.println(String.format("Attempt\t\t 1\t4\t8\n"));
    
    for (int i = 0; i < 10; i++)
    {
        final long b1 = backoff(i, 120, 1);
        final long b2 = backoff(i, 120, 4);
        final long b3 = backoff(i, 120, 8);
    
        System.out.println(String.format("%d\t\t %d\t%d\t%d", i, b1, b2, b3));    
    }
    
    
    		 1	4	8
    
    0		 0	0	0
    1		 1	2	4
    2		 2	6	12
    3		 4	14	28
    4		 8	30	60
    5		 16	62	120
    6		 32	120	120
    7		 64	120	120
    8		 120	120	120
    9		 120	120	120
    
    

    From the results above we can see that changing the multiplier can have significant implications. The larger the multiplier the faster we will be approaching our maxDelay and we will have longer paused between each attempt.

    In next post, we will create a Data Retrieval Service that will utilize Exponential backoff.

  • PhantomSQL 2.0

    Since the beginning of this project, I have learned many lessons.

    First of all the syntax of the language was to closely related to SQL, as this was the language that I wanted to mimic and fit into this framework. Main reason for that was that I wanted something familiar to the end user, I was hoping for easier adoption rate. Secondly, the lack of Web 2.0+ futures. They were not thought out in the beginning and shoehorning them in just made no sense and even more complicated the language.

    Example : Grab data from woot (v1)

    foreach @srcUrl : [http://www.woot.com/, http://home.woot.com/, http://shirt.woot.com/, http://kids.woot.com/]
    begin
    	set @doc = select 
    			xpaths("//*[@class='amount']/text()"),
    			xpaths("//h2[@class='fn']/text()"),
    			xpaths("//*[@class='lightBox' and @rel='sale']/img/@src"),			
    			xpaths("//*[@class='wootOffProgressBarValue']/@style")
    		 from @srcUrl
    		
    	set @images = @document.xpaths("//*[@class='lightBox' and @rel='sale']/@href")
    	set @first = @doc[0]
    	set @price = @first[0]	
    	set @title = @first[1]
    	set @image = @first[2]	
    	set @wootoff = @first[3].split(":")
    	set @wootoff = @wootoff[1].replace("%", "")
    
    	insert  products (@srcUrl, @title, @price, @wootoff, @image, @images)
    end
    

    Couple problems that this introduced, first of all, we were constrained by the original language structure. Let’s take simple snippet

    set @price = @first[0]

    It might not look like much but this type of declaration is very declarative and it could easily be removed from the syntax. 

    Another drawback was the lack of extensibility.  Many of the basic functions have been hardcoded into the parser, thus adding any new language extension was dependent on recreating the AST. Only later and ‘dynamic’ methods have been added but again they were an afterthought and seem more like a hack.

    There was no way to reuse existing libraries, basically, this means I had to reimplement all the features that someone already did. This only became apparent to me when I needed to run a md5 checksum on one of the downloaded files. 

    Another issue for me was that there was no good support for collections (List, Set, Dictionary). There was the basic support for ‘list’ and then later ‘dictionary ‘ but again it was not thought out and missed many features.

    As we can see there were quite a few design issues that were not thought out in the initial version.  Many of this thing have been learned though running the system on real word problems. As long as we are able to take this and adapt I think we will be in good shape.

    Roadmap

    • Reworking language syntax
      • Based on modern languages / frameworks (EcmaScript / Python / Rubby / SQL/ Node.js)
      • Web 2.0 (Support for extracting data from dynamic websites)
    • Distributed Processing(Will run on a distributed clustering framework)
    • Package Manager (PhantomSQL Package Manager(PPM))

     

  • Run MD5 check sum against all files in a directory

    Couple snippets that allow us to run checksum and get unique md5 checksums.

    This is two step process. First, we obtain our md5 checksum for all files

    find -type f -exec md5sum "{}" + > /opt/checklist.chk
    

    This produces file with following contents

    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif6712032974632727465.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif174464329785828524.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif6775939766281585264.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif7205305688614612348.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif3909999865608008175.tiff
    

    Next we parse and get only unique checksums.

    cat  /opt/checklist.chk | awk '{split($0, a, " "); if(!seen[a[1]]++) print a[1]}'
    

    This produces our distinct checksums

    71cc452a8ac5a27c32a83e6a0909e7ae
    
  • Random number between two values

    This is a small utility class that allows us to obtain a random number between two values that are uniformly distributed in the range of ‘low’ to ‘high’. This works for floats, doubles and integers.

    The inner working of this class are straight forward, our uniform(int, int) method uses the nextInt(int) method of Random class which already allows us to pass the upper bound. Float and Double work by obtaining a value in range [0.0, 1.0] and then scaling it accordingly between our ‘low’ and ‘high’

    As this is meant for use in multithreaded environment I am using java.util.concurrent.ThreadLocalRandom rather than java.util.Random for performance reasons.

    import java.util.concurrent.ThreadLocalRandom;
    
    import java.util.concurrent.ThreadLocalRandom;
    
    public class RandomUtil
    {
        public static int uniform(final int low, final int high)
        {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            return rand.nextInt(high - low) + low;
        }
    
        public static float uniform(final float low, final float high)
        {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            return rand.nextFloat() * (high - low) + low;
        }
    
        public static double uniform(final double low, final double high)
        {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            return rand.nextDouble() * (high - low) + low;
        }
    
        public static double nextDouble()
        {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            return rand.nextDouble();
        }
    
        public static boolean nextBoolean()
        {
            final ThreadLocalRandom rand = ThreadLocalRandom.current();
            return rand.nextBoolean();
        }
    }
    
  • Procedural lightning effect Unity

    DRAFT

    This is a basic tutorial on how to create procedural lightning effect in Unity, this is my first attempt at using Unity so if you think there are bugs,issues or better ways of doing things let me know.

    I am using a two step process

    1) Generator
    2) Renderer

    I like to have them separated for couple different reasons but mainly to allow me to render them differently and create different lighting like effects.

    Generator is responsible for generating segments and renderer is responsible for rendering segments to the screen.

    My original version used a LineRenderer but I decided to go with a Mesh/MeshFilter for rendering as that gives me more control.  Each segment creates a new quad that is added to our mesh.

    After 1 generation

    light-mesh-001

    Results after first pass.

    light-001    light-002    light-003

    Current status 

    light-mesh-002    light-mesh-003    light-mesh-004

    Implementation 

    Segment class

    public class Segment 
    {
        public Vector2 start;
    
        public Vector2 end;
    
        public int generation;
        
        public Segment(Vector2 start, Vector2 end) : this(start, end, 0)
        {
                   
        }
    
        public Segment(Vector3 start, Vector2 end, int generation)
        {
            this.start = start;
            this.end = end;
            this.generation = generation;
        }
    }
    
  • Generate ID from UUID

    This is a method to generate a long id in the positive space.

    There are few issues to consider with this method
    – UUID is 16 bytes / 128 bits
    – Long is 8 bytes / 64 bits

    This means that we will loose some information, if we don’t want to lose that we could use a BigInteger but In this case we are dealing with longs.

    
        /**
         * Gnereate unique ID from UUID in positive space
         * @return long value representing UUID
         */
        private Long generateUniqueId()
        {
            long val = -1;
            do
            {
                final UUID uid = UUID.randomUUID();
                final ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
                buffer.putLong(uid.getLeastSignificantBits());
                buffer.putLong(uid.getMostSignificantBits());
                final BigInteger bi = new BigInteger(buffer.array());
                val = bi.longValue();
            } while (val < 0);
            return val;
        }
    

    This works simply by creating new BigInteger from parts of UUID object, and then getting the longValue. We also make sure that the ID is in positive space, if its not we simply repeat the process. During testing most cases completed in one iteration but it did encounter few runs that reached four iterations.

  • Configuring Java JDK on Ubuntu

    This is an easy way to configure java on a linux box, all this information is available online.

    First we need to obtain the build.

    sudo wget http://192.168.201.47:8000/jdk-7u75-linux-x64.gz

    Extract from tar

     sudo tar xzvf  jdk-7u75-linux-x64.gz

    Create symbolic link so we can later update the version

    sudo ln -s /opt/jdk1.7.0_75/ /opt/java

    we edit the /etc/profile and add following two lines

    export JAVA_HOME=/opt/java
    export PATH=$JAVA_HOME/bin:$PATH
    

    finally we ‘source’ the file

    source /etc/profile
    

    At this point you should be ready to go, we can verify this by executing

    java -version