Golos/Steem PHP Event Listener [v0.0.1rc2]

in utopian-io •  10 months ago

golos-php-event-listener

PHP event listener for STEEM/GOLOS blockchains

Github or packagist with MIT license. Author @t3ran13

Basic Usage

You need for working your app

  • database manager
  • events handlers
  • start script for cron

Database manager

Lib has ready for using RedisManager (DB structure see below), which you can to extend and add new necessary functions for your events handlers, as below

<?php
namespace MyApp;

class RedisManager extends \GolosPhpEventListener\app\db\RedisManager
{
    public function connect()
    {
        if ($this->connect === null) {
            $this->connect = new \Predis\Client(
                [
                    'scheme'             => 'tcp',
                    'host'               => 'redis',
                    'port'               => 6379,
                    'database'           => 0,
                    'read_write_timeout' => -1,
                    'async'              => false,
                    'password'           => getenv('REDIS_PSWD')
                ]
            );
        }

        return $this->connect;
    }
    
    public function you_func()
    {
        //some code
    }
}

or you can create own DB manager

<?php
namespace MyApp;

use GolosPhpEventListener\app\db\DBManagerInterface;

class MyManager implements DBManagerInterface
{
    public function connect() 
    {
        if ($this->connect === null) {
            $this->connect = new \Predis\Client(
                [
                    'scheme'             => 'tcp',
                    'host'               => 'redis',
                    'port'               => 6379,
                    'database'           => 0,
                    'read_write_timeout' => -1,
                    'async'              => false,
                    'password'           => getenv('REDIS_PSWD')
                ]
            );
        }

        return $this->connect;
    }
    /**
         * add new event listener
         *
         * @param int   $id
         * @param array $options
         *
         * @return void
         */
    public function listenerAdd($id, $options) {
     // TODO: Implement listenerAdd() method.
    }
    /**
         * remove all events from listeners list
         *
         * @return void
         */
    public function listenersListClear() {
     // TODO: Implement listenersListClear() method.
    }
    /**
         * get listeners list
         *
         * @return array
         */
    public function listenersListGet() {
     // TODO: Implement listenersListGet() method.
    }
    /**
         * update listener data
         *
         * @param int   $id
         * @param array $options
         *
         * @return mixed
         */
    public function listenerUpdateById($id, $options) {
     // TODO: Implement listenerUpdateById() method.
    }
    /**
         * get listener data by id
         *
         * @param int         $id
         * @param null|string $field
         *
         * @return mixed
         */
    public function listenerGetById($id, $field = null) {
     // TODO: Implement listenerGetById() method.
    }
    /**
         * @param int   $id
         * @param array $options
         *
         * @return int process id in db
         */
    public function processAdd($id, $options) {
     // TODO: Implement processAdd() method.
    }
    /**
         * update process data
         *
         * @param int   $id
         * @param array $options
         *
         * @return mixed
         */
    public function processUpdateById($id, $options) {
     // TODO: Implement processUpdateById() method.
    }
    /**
         * get process data by id
         *
         * @param int         $id
         * @param null|string $field
         *
         * @return mixed
         */
    public function processInfoById($id, $field = null) {
     // TODO: Implement processInfoById() method.
    }
    /**
         * remove all process from list
         *
         * @return void
         */
    public function processesListClear() {
     // TODO: Implement processesListClear() method.
    }
    /**
         * get processes list
         *
         * @return array
         */
    public function processesListGet() {
     // TODO: Implement processesListGet() method.
    }
    /**
         * remove all events from list
         *
         * @return void
         */
    public function eventsListClear() {
     // TODO: Implement eventsListClear() method.
    }
    /**
         * @param int   $listenerId
         * @param array $trx
         *
         * @return bool status
         */
    public function eventAdd($listenerId, $trx) {
     // TODO: Implement eventAdd() method.
    }
    /**
         * @param int $listenerId
         * @param int $blockN
         * @param int $trxInBlock
         *
         * @return mixed status
         */
    public function eventDelete($listenerId, $blockN, $trxInBlock) {
     // TODO: Implement eventDelete() method.
    }
    /**
         * @param int $listenerId
         *
         * @return int
         */
    public function eventsCountByListenerId($listenerId) {
     // TODO: Implement eventsCountByListenerId() method.
    }
    /**
         * @param int $listenerId
         *
         * @return array as key => trx
         */
    public function eventsListByListenerId($listenerId) {
     // TODO: Implement eventsListByListenerId() method.
    }
    /**
         * insert error to error log list
         *
         * @param int    $id
         * @param string $error
         *
         * @return mixed
         */
    public function listenerErrorInsertToLog($id, $error) {
     // TODO: Implement listenerErrorInsertToLog() method.
    }
    /**
         * insert error to error log list
         *
         * @param int    $id
         * @param string $error
         *
         * @return mixed
         */
    public function processErrorInsertToLog($id, $error) {
     // TODO: Implement processErrorInsertToLog() method.
    }
    
}

Events handlers

Each Handler have to implements HandlerInterface and ProcessInterface, you can create own or extends from HandlerAbstract.
When events are be found function start() will be called.

<?php
namespace MyApp;

use GolosPhpEventListener\app\handlers\HandlerAbstract;


class VoteHandler extends HandlerAbstract
{
    public function start()
    {
        pcntl_setpriority($this->priority, getmypid());

        //some code
    }
}

Start script for cron

When we have DB manager and event handler and can create app

<?php
namespace MyApp;

use GolosPhpEventListener\app\AppConfig;
use GolosPhpEventListener\app\process\BlockchainExplorerProcess;
use GolosPhpEventListener\app\process\EventsHandlersProcess;
use GolosPhpEventListener\app\process\MainProcess;

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
//error_reporting(E_ALL);
define('PATH', __DIR__);
require __DIR__ . "/Autoloader.php"; // only in GrapheneNodeClient project
require __DIR__ . '/vendor/autoload.php';




echo PHP_EOL . '------ StartApp.php ------' . PHP_EOL;

$appConfig = new AppConfig();
//$appConfig->addListener(['op:1:voter' => 'fafnur', 'op:0' => 'vote'], new PostIsCreatedHandler()); //from defined user
$appConfig->addListener(['op:0' => 'vote'], new PostIsCreatedHandler());

$dbRedis = New MyManager();
$mainProcess = new MainProcess(
    $appConfig,
    $dbRedis
);
//$mainProcess->ClearAllData();


$currentDatetime = (new \DateTime())->sub(new \DateInterval('PT0H30M'))->format('Y-m-d H:i:s');
if (
    $mainProcess->getStatus() === ProcessInterface::STATUS_STOPPED
    || $mainProcess->getStatus() === null
    || (
        $mainProcess->getStatus() === ProcessInterface::STATUS_RUNNING
        && $currentDatetime > $mainProcess->getLastUpdateDatetime()
    )
) {
    echo PHP_EOL . '------ new MainProcess is started ------';

    $dbClassName = get_class(New RedisManager());
    $connectorClassName = 'GrapheneNodeClient\Connectors\WebSocket\GolosWSConnector';
    $blockchainExplorerProcess = new BlockchainExplorerProcess($dbClassName, $connectorClassName);
    $blockchainExplorerProcess->setLastBlock(16238400);
    
    $mainProcess->processesList = [
        $blockchainExplorerProcess, //search events
        new EventsHandlersProcess($dbClassName) //calls events handlers
    ];

    try {
        $mainProcess->start();

    } catch (\Exception $e) {

        $msg = '"' . $e->getMessage() . '" ' . $e->getTraceAsString();
        echo PHP_EOL . ' --- mainProcess got exception ' . $msg . PHP_EOL;
        $mainProcess->errorInsertToLog(date('Y-m-d H:i:s') . '   ' . $msg);

    } finally {

        $mainProcess->setStatus(ProcessInterface::STATUS_STOPPED);
        exit(1);
    }
} else {
    echo PHP_EOL . '------ other StartApp.php is working ------';
}

Add this script to cron.

DB RedisManager

DB structure:

  • DB0
    • app:processes:{id}:last_update_datetime

    • app:processes:{id}:status

    • app:processes:{id}:mode

    • app:processes:{id}:pid

    • app:processes:{id}:handler

    • app:processes:{id}:data:last_block

    • app:listeners:{id}:last_update_datetime

    • app:listeners:{id}:status

    • app:listeners:{id}:mode

    • app:listeners:{id}:pid

    • app:listeners:{id}:handler

    • app:listeners:{id}:data:last_block

    • app:listeners:{id}:conditions:{n}:key

    • app:listeners:{id}:conditions:{n}:value

    • app:events:{listener_id}:{block_n}:{trx_n_in_block}

App example

Example of the app base on golos-php-event-listener you can see here https://github.com/t3ran13/golos-rating-auto-reward


It is better with each commit

Total 93 commits were made and it were done by me during last 14 days:

  • lib namespace update
  • app autoloder
  • upd composer.json + readme
  • old delete
  • upd processes logic
  • remove example code
  • hide log info
  • upd BlockchainExplorerProcess
  • MIT LICENSE
  • fix BlockchainExplorerProcess
  • fix default value
  • upd BlockchainExplorerProcess
  • upd Process isStartNeeded logic
  • added clear all data method for MainProcess
  • fix BlockchainExplorerProcess
  • clear code MainProcess
  • upd RedisManager
  • upd HandlerAbstract and ProcessAbstract
  • fix func name in MainProcess
  • fix ProcessAbstract
  • upd BlockchainExplorerProcess
  • fix bug BlockchainExplorerProcess
  • hide debug info
  • fix bug in RedisManager for events list
  • upd datetime format
  • upd README.md
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you for your contribution.

Your contribution has been evaluated according to Utopian rules and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post,Click here


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

·

thank you!
it is cool that i can see feadback https://review.utopian.io/result/3/3322244

could you show example of great commit messages?

·
·

Hey @t3ran13, have a look at the commits of this repo.
https://github.com/mcfarhat/gk-steemit-info/commits/master

·
·
·

thank you!

что-то перестал ко мне приходить...

·

утопиан?

·
·

буси. но он не лайкает меня уже месяц.
на утопиан есть плюшки?

·
·
·

а я тут причем)
на утопиан есть

·
·
·
·

мне сказали, что утопиан не для блогеров. что он для прогеров и технарей.

·
·
·
·
·

не совсем. там переводы публячить можно либо инструкции)

Hey @t3ran13
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Contributing on Utopian
Learn how to contribute on our website or by watching this tutorial on Youtube.

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!