1

Trying to make a dice-roll function in my telegram bot. How it works right now:

  • When a user sends "roll" bot replies with sendDice method and sends another message with result like "you rolled 5, you won and blah-blah .." > how it looks <

The problem is — the second message should not appear instantly, ideally after dice-roll animation is finished. My first and obvious try on that was to add "sleep(3)" before sending the second message, and it worked fine, until I realized it completely delays the execution of my script for those 3 seconds. (if two users rolled at the same time, one of the users has to wait until another guy's roll will be finished). So it's not cool

What can I use? :c

  • 1
    For async PHP you can fork your code yourself using system calls or use a library like [amphp](https://amphp.org/) – Code4R7 Jan 21 '21 at 15:49
  • Sounds good, man! But since I'm a php-newbie I don't really know how to "fork my code using system calls", lol (I googled but didn't get much of it). It would be super cool if you could clarify this a little. – marv flacko Jan 21 '21 at 17:45
  • Can you place an example of your code here so we can view it? – centralhubb.com Jan 22 '21 at 11:52

2 Answers2

0

From Wikipedia:

In computing, [..] fork is an operation whereby a process creates a copy of itself.

When your PHP script runs, you can create multiple processes that interact with each other. Those processes run concurrently and asynchronous. This way you can have one process waiting to send the message, while the rest of the script continues to run.

Instead of starting another process, you could also start another thread. The technical difference between the two is explained here: Forking vs Threading

PHP offers Process Control Extensions for both forking and threading. You might want to check out the example in the PHP documentation for pcntl_fork().

Depending on your needs, you might want to use a framework designed to handle concurrency throughout your application. If that is the case, I would recommend amphp.

Code4R7
  • 2,600
  • 1
  • 19
  • 42
0

The easiest option is to add the "task" to the "queue". The queue can be a table in the database with timestamps and chat id, when and to whom to send a message. Start another process, for example, which is started by cron, and it works for one minute. During that minute, he goes to the database and checks to see if there is something that needs to be sent now.

Crontab config

Open crontab

sudo crontab -e

Add next string

* * * * * php /path/to/cron.php >> /path/to/log/file/for/debug.log 2>&1

Cron run your script every 1 minute.

Cron.php "live" 60 second cron.php:

    $now = time();
    $expectedTime = $now + 60;
    while (true) {
        Worker::run();
        if ($expectedTime < time()) {
            die(0);
        }
    }

Where Worker::run() your method, which get records from db, check timestamp and send message