| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- <?php declare(strict_types=1);
- include __DIR__ . '/vendor/autoload.php';
- use Ripple\Database\Interface\AbstractResultSet;
- use Ripple\Database\MySQL\Client;
- use Ripple\Net\Http\Server;
- use Ripple\Net\Http\Server\Request;
- use Ripple\Sync\Channel;
- use Ripple\Sync\WaitGroup;
- use Ripple\Worker;
- use Ripple\Worker\Manager;
- use Ripple\Net\Http;
- use function Co\go;
- use function Co\wait;
- class Setup
- {
- /**
- * @var string
- */
- public static string $dateFormatted;
- /**
- * @var null|callable
- */
- private static $fortunesRenderer = null;
- /**
- * @return void
- */
- public static function dateRefresh(): void
- {
- try {
- $date = new DateTime('now', new DateTimeZone('GMT'));
- } catch (Throwable) {
- return;
- }
- Setup::$dateFormatted = $date->format('D, d M Y H:i:s T');
- }
- /**
- * @return int
- */
- public static function randomInt(): int
- {
- try {
- return \random_int(1, 10000);
- } catch (Throwable $e) {
- return \mt_rand(1, 10000);
- }
- }
- /**
- * @param mixed $value
- * @return int
- */
- public static function clamp(mixed $value): int
- {
- if (!\is_numeric($value) || $value < 1) {
- return 1;
- }
- if ($value > 500) {
- return 500;
- }
- return \intval($value);
- }
- /**
- * @param array $rows
- * @return string
- */
- public static function renderFortunes(array $rows): string
- {
- if (self::$fortunesRenderer === null) {
- $code = \file_get_contents(__DIR__ . '/fortunes.php');
- if ($code === false) {
- return '';
- }
- $renderer = static function (array $scope) use ($code): string {
- foreach ($scope as $key => $value) {
- $$key = $value;
- }
- \ob_start();
- eval('?>' . $code);
- return (string) \ob_get_clean();
- };
- self::$fortunesRenderer = $renderer;
- }
- /** @var callable $renderer */
- $renderer = self::$fortunesRenderer;
- return $renderer(['rows' => $rows]);
- }
- }
- $manager = new Manager();
- $worker = new class () extends Worker {
- /**
- * @var Server
- */
- private Server $server;
- /**
- * @var Channel
- */
- private Channel $STM_queryWorldWhereID;
- /**
- * @var Channel
- */
- private Channel $STM_updateWorldRandomNumber;
- /**
- * @var Channel
- */
- private Channel $STM_queryFortune;
- /**
- * @return void
- */
- public function register(): void
- {
- $this->count = 32;
- $context = \stream_context_create([
- 'socket' => [
- 'so_reuseport' => 1,
- 'so_reuseaddr' => 1
- ]
- ]);
- $this->server = Http::server('http://0.0.0.0:8080', $context);
- }
- /**
- * @return void
- */
- public function boot(): void
- {
- Setup::dateRefresh();
- go(static function () {
- while (1) {
- \Co\sleep(1);
- Setup::dateRefresh();
- }
- });
- $this->STM_queryWorldWhereID = new Channel(10);
- $this->STM_updateWorldRandomNumber = new Channel(10);
- $this->STM_queryFortune = new Channel(10);
- for ($i = 0; $i < 10; $i++) {
- $client = new Client(
- 'mysql:host=tfb-database;port=3306;dbname=hello_world',
- 'benchmarkdbuser',
- 'benchmarkdbpass',
- );
- $this->STM_queryWorldWhereID->send($client->prepare('SELECT id, randomNumber FROM World WHERE id = ?'));
- $this->STM_updateWorldRandomNumber->send($client->prepare('UPDATE World SET randomNumber = ? WHERE id = ?'));
- $this->STM_queryFortune->send($client->prepare('SELECT * FROM `Fortune`'));
- }
- $this->server->onRequest = fn (Request $request) => $this->onRequest($request);
- $this->server->listen();
- }
- /**
- * @param Request $request
- * @return void
- */
- public function onRequest(Request $request): void
- {
- switch ($request->SERVER['REQUEST_URI']) {
- case '/json':
- {
- $request->respondJson(
- ['message' => 'Hello, World!'],
- ['Date' => Setup::$dateFormatted]
- );
- break;
- }
- case '/db':
- {
- $statement = $this->STM_queryWorldWhereID->receive();
- $statement->execute([Setup::randomInt()]);
- $request->respondJson($statement->fetch(AbstractResultSet::ASSOC_ARRAY), ['Date' => Setup::$dateFormatted]);
- $this->STM_queryWorldWhereID->send($statement);
- break;
- }
- case '/queries':
- {
- $queries = Setup::clamp($request->GET['queries'] ?? 1);
- $results = [];
- $waitGroup = new WaitGroup();
- $waitGroup->add($queries);
- while ($queries--) {
- go(function () use (&$results, $waitGroup) {
- $statement = $this->STM_queryWorldWhereID->receive();
- $statement->execute([Setup::randomInt()]);
- $results[] = $statement->fetch(AbstractResultSet::ASSOC_ARRAY);
- $this->STM_queryWorldWhereID->send($statement);
- $waitGroup->done();
- });
- }
- $waitGroup->wait();
- $request->respondJson($results, ['Date' => Setup::$dateFormatted]);
- break;
- }
- case '/fortunes':
- {
- $statement = $this->STM_queryFortune->receive();
- $statement->execute();
- $rows = $statement->fetchAll(AbstractResultSet::ASSOC_ARRAY);
- $this->STM_queryFortune->send($statement);
- $rows[] = ['id' => 0, 'message' => 'Additional fortune added at request time.'];
- \usort($rows, function ($a, $b) {
- return $a['message'] <=> $b['message'];
- });
- $request->respondHtml(
- Setup::renderFortunes($rows),
- [
- 'Date' => Setup::$dateFormatted,
- 'Content-Type' => 'text/html; charset=UTF-8'
- ]
- );
- break;
- }
- case '/updates':
- {
- $queries = Setup::clamp($request->GET['queries'] ?? 1);
- $results = [];
- $waitGroup = new WaitGroup();
- $waitGroup->add($queries);
- while ($queries--) {
- go(function () use (&$results, $waitGroup) {
- $statement = $this->STM_queryWorldWhereID->receive();
- $update = $this->STM_updateWorldRandomNumber->receive();
- $statement->execute([Setup::randomInt()]);
- $row = $statement->fetch(AbstractResultSet::ASSOC_ARRAY);
- $row['randomNumber'] = Setup::randomInt();
- $results[] = $row;
- $update->execute([$row['randomNumber'], $row['id']]);
- $this->STM_queryWorldWhereID->send($statement);
- $this->STM_updateWorldRandomNumber->send($update);
- $waitGroup->done();
- });
- }
- $waitGroup->wait();
- $request->respondJson($results, ['Date' => Setup::$dateFormatted]);
- break;
- }
- case '/plaintext':
- {
- $request->respond(
- 'Hello, World!',
- [
- 'Content-Type' => 'text/plain; charset=utf-8',
- 'Date' => Setup::$dateFormatted
- ]
- );
- break;
- }
- default:
- {
- $request->respond('Not Found', [], 404);
- }
- }
- }
- };
- $manager->add($worker);
- $manager->run();
- wait();
|