public function run($queue = 'queue')
    {   
        // notify its up
        echo ' * Worker online. waiting for tasks.', "\n";

        // define job
        $callback = function($message) {
            // notify once a task is received
            echo " * a task is received", "\n";

            // get the data
            $data = json_decode($message->body, true);

            // get application
            $app = ucfirst($data['APPLICATION']);

            //remove starting \\ and append the Job holder
            $app = substr($app, 1).'\\Job\\';

            // extract the job to perform
            $task = str_replace(' ', '\\', ucwords(str_replace('-', ' ', $data['TASK'])));
            $task = $app.$task;

            $attempts = isset($data['RETRY']) ? $data['RETRY'] : 0;

            try {

                // if there's not a class
                if(!class_exists($task)) {
                    //throw
                    throw new Exception('task do not exist', 404);
                }

                //instantiate the job
                $job = new $task();

                // set data and run the process
                $job->setData($data)->run();

                // once done, notify again, that it is done
                echo " * task is done", "\n";

                // set or flag that the worker is free
                $message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
            } catch (Exception $e) {
                // once an exception is encountered, notify that task is not done
                echo " * task not done", "\n";
                echo $e->getMessage()."\n";

                if ($attempts && $message->delivery_info['redelivered'] > $attempts) {
                    echo " * Requeueing ....", "\n";
                    // set or flag that the task is not done and the worker is free and requeue task
                    $message->delivery_info['channel']->basic_nack($message->delivery_info['delivery_tag'], false, true);
                }

                // set or flag that the task is not done and the worker is free
                $message->delivery_info['channel']->basic_nack($message->delivery_info['delivery_tag']);
            }
        };

        // worker consuming tasks from queue
        $this->channel->basic_qos(null, 1, null);
        
        // now we need to catch the channel exception
        // when task does not exists in our queue
        try {
            // comsume messages on queue
            $this->channel->basic_consume($queue, '', false, false, false, false, $callback);
        } catch(\PhpAmqpLib\Exception\AMQPProtocolChannelException $e) {
            // notify that task does not exists
            echo " * Task does not exists, creating task. Please re-run the worker. \n";
                
            // create the init queue
            eve()->queue('init', array())->save();
        }
        
        while(count($this->channel->callbacks)) {
            $this->channel->wait();
        }

        $this->channel->close();
        $this->connection->close();
        echo 'Closing Dispatcher'. PHP_EOL;
    }