public function testPoolGc() { $pool = new Pool(1, PoolTestWorker::class, [new stdClass(), new Threaded()]); $work = new PoolTestWork(); $pool->submit($work); while (@$i++ < 2) { $pool->submit(new PoolTestWork()); # nothing to assert, no exceptions please } $pool->submitTo(0, new PoolTestWork()); # nothing to assert, no exceptions please /* synchronize with pool */ $sync = new PoolTestSync(); $pool->submit($sync); $sync->synchronized(function ($sync) { if (!$sync->finished) { $sync->wait(); } }, $sync); $pool->collect(function ($task) { $this->assertTrue($task->isGarbage()); return true; }); $pool->shutdown(); }
public function submitTask(AsyncTask $task) { if ($task->isGarbage()) { return; } $this->tasks[$task->getTaskId()] = $task; $this->pool->submit($task); }
/** * Submits a asynchronous task to the Pool * If the AsyncTask sets a result, you have to get it so it can be deleted * * @param AsyncTask $task * * @return void */ public function scheduleAsyncTask(AsyncTask $task) { $id = $this->nextId(); $task->setTaskId($id); $this->asyncPool->submit($task); $this->asyncTaskStorage[$id] = $task; ++$this->asyncTasks; }
public function useMultiCore1() { $core = $this->getCoreCount(); $pool = new \Pool($core); for ($i = 0; $i < $core; $i++) { $pool->submit(new ProveWorker()); } }
public function submit(Threaded $threaded) { if (!$threaded instanceof PipeAware or !$threaded instanceof VolatileAware) { throw new \InvalidArgumentException("Threadeds submitted to OnDemandePool should implement both PipeAware and VolatileAware"); } $threaded->setPipe($this->getPipe()); $threaded->setVolatile($this->getPacket()); parent::submit($threaded); }
protected function execute(InputInterface $input, OutputInterface $output) { $pool = new \Pool($input->getOption('threads'), \Worker::class); foreach ($input->getArgument('indexes') as $index) { $pool->submit(new IndexerRunner($input->getOption('indexer'), $input->getOption('config'), $index)); } $pool->shutdown(); $pool->collect(function (IndexerRunner $work) use($output) { $output->writeln($work->return); }); }
public function __construct($threadSayisi, BurtayThread $sinif) { $pool = new Pool($threadSayisi); $is_listesi = array(); for ($i = 1; $i <= $threadSayisi; $i++) { $is_listesi[] = new burtayThreadPool($sinif); } foreach ($is_listesi as $liste) { $pool->submit($liste); } $pool->shutdown(); }
public function submit(\Threaded $thread, $loop) { parent::submit($thread); return Observable::create(function (ObserverInterface $observer) use($thread, $loop) { while ($thread->isRunning()) { $loop->tick(); //var_dump($thread->isRunning()); //usleep(100); } $observer->onNext(new Event('/thread/ok', $thread)); $observer->onCompleted(); }); }
private function testPool() { $initTime = microtime(true); $pool = new \Pool(8, \Worker::class); for ($i = 0; $i < 10; $i++) { $pool->submit(new Work()); } $initTime = microtime(true) - $initTime; $finishTime = microtime(true); $pool->shutdown(); $pool->collect(function (Work $work) { echo 'Work of ', get_class($work), ' #', $work->i, ' - ', $work->getWork(), PHP_EOL; }); $finishTime = microtime(true) - $finishTime; return [$initTime, $finishTime]; }
public static function Init() { $config = \Rds\Configuration::get(); $boot = \Rds\Bootstrap::getInstace($config); $totalPages = $boot->getTotalPages(); if ($totalPages > 0) { $pool = new \Pool($config["app"]["workers"], \Rds\Worker::class, array("Vendor/autoload.php", new \Rds\StackableConfig($config))); for ($page = 1; $page <= $totalPages; $page++) { $task = new \Rds\Task($page); $pool->submit($task); } $pool->shutdown(); $pool->collect(function ($work) { return $work->isGarbage(); }); } }
class Example extends Thread { public function run() { dump('foobar'); } } // Faulty example ////////////////////////////////////////////////////////////////////// $job = new Example(); $job->start(); $job->join(); // Now let's fix our example ////////////////////////////////////////////////////////////////////// class AutoloadingWorker extends Worker { public function run() { require 'vendor/autoload.php'; } } // Create our worker and stack our job on it $worker = new AutoloadingWorker(); $job = new Example(); $worker->stack($job); $worker->start(); $worker->join(); // Or use a pool and specify our custom worker $pool = new Pool(5, AutoloadingWorker::class); $pool->submit(new Example()); $pool->shutdown();
<?php /* include autoloader normally */ require_once "vendor/autoload.php"; use Auto\Autoloader; use Auto\Task; /* create pool of workers of the specified class, passing the specified path to autoloader */ $pool = new Pool(4, Autoloader::class, ["vendor/autoload.php"]); /* submit a task to the pool */ $pool->submit(new Task("Hello World!")); /* in the real world, do some ::collect somewhere */ /* shutdown, because explicit is good */ $pool->shutdown();
/* getting a value on the channel shall cause callers to wait until it's available */ public final function __get($key) { return $this->synchronized(function () use($key) { while (!isset($this[$key])) { $this->wait(); } return $this[$key]; }); } } class Routine extends Threaded { public function __construct(Channel $channel) { $this->channel = $channel; } public function run() { /* sending on the channel */ $this->channel["message"] = "Hello World"; $this->channel["gold"] = 3.462; } protected $channel; } $channel = new Channel(); $pool = new Pool(4); $pool->submit(new Routine($channel)); /* recving on the channel */ printf("Message: %s, Gold: %.3f\n", $channel["message"], $channel["gold"]); $pool->shutdown();
public function run() { $mysqli = $this->worker->getConnection(); $result = $mysqli->query($this->sql); if ($result) { while ($row = $result->fetch_assoc()) { $rows[] = $row; } } $this->result = $rows; } public function getResult() { return $this->result; } protected $sql; protected $result; } $pool = new Pool(4, "Connect", ["localhost", "root", "", "mysql"]); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->submit(new Query("SHOW PROCESSLIST;")); $pool->shutdown(); /* ::collect is used here for shorthand to dump query results */ $pool->collect(function ($query) { var_dump($done = $query->getResult()); return count($done); });
} /* Shutdown the pool of threads cleanly, retaining exit status locally */ public function shutdown() { foreach ($this->workers as $worker) { $this->status[$worker->getThreadId()] = $worker->shutdown(); } } } $start = microtime(true); /* Create a pool of ten threads */ $pool = new Pool(10); /* Create and submit an array of Stackables */ $work = array(); while (++$target < 100) { $work[] = $pool->submit(new ExampleWork(array_rand($_SERVER))); } $pool->shutdown(); /* * Look inside */ $runtime = microtime(true) - $start; if ($_SERVER["HTTP_HOST"]) { echo "<pre>"; } printf("---------------------------------------------------------\n"); printf("Executed %d tasks in %f seconds in %d threads\n", count($work), $runtime, 10); printf("---------------------------------------------------------\n"); if ($_SERVER["HTTP_HOST"]) { printf("%s | %.3fMB RAM\n", $_SERVER["SERVER_SOFTWARE"], memory_get_peak_usage(true) / 1048576); } else {
public function submit($command) { return parent::submit(new CommandJob($command)); }
$this->worker->logger->log("%s executing in Thread #%lu", __CLASS__, $this->worker->getThreadId()); $this->setGarbage(); } } class SafeLog extends Stackable { protected function log($message, $args = []) { $args = func_get_args(); if ($message = array_shift($args)) { echo vsprintf("{$message}\n", $args); } } } $pool = new Pool(8, 'WebWorker', [new SafeLog()]); $pool->submit($w = new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->submit(new WebWork()); $pool->shutdown(); $pool->collect(function ($work) {
{ public function run() { } } /* stage and data reference arrays */ $one = []; $two = []; $data = []; $pool = new Pool(8); $pool->start(); /* construct stage one */ while (count($one) < 10) { $staging = new StagingData(); /* maintain reference counts by storing return value in normal array in local scope */ $one[] = $pool->submit(new StageOne($staging)); /* maintain reference counts */ $data[] = $staging; } /* construct stage two */ while (count($one)) { /* find completed StageOne objects */ foreach ($one as $id => $job) { /* if done is set, the data from this StageOne can be used */ if ($job->done) { /* use each element of data to create new tasks for StageTwo */ foreach ($job->data as $chunk) { /* submit stage two */ $two[] = $pool->submit(new StageTwo($chunk)); } /* no longer required */
$linksTagged += $tmp['linkstagged']; $tmp = null; unlink(IAPROGRESS . WIKIPEDIA . UNIQUEID . "workers/{$entry}"); } unset($tmp); file_put_contents(IAPROGRESS . WIKIPEDIA . UNIQUEID . "stats", serialize(array('linksAnalyzed' => $linksAnalyzed, 'linksArchived' => $linksArchived, 'linksFixed' => $linksFixed, 'linksTagged' => $linksTagged, 'pagesModified' => $pagesModified, 'pagesAnalyzed' => $pagesAnalyzed, 'runstart' => $runstart))); } if (file_exists(IAPROGRESS . WIKIPEDIA . UNIQUEID . "workers/")) { closedir($handle); } $workerQueue = new Pool($workerLimit); foreach ($pages as $tid => $tpage) { $pagesAnalyzed++; $runpagecount++; echo "Submitted {$tpage['title']}, job " . ($tid + 1) . " for analyzing...\n"; $workerQueue->submit(new ThreadedBot($tpage['title'], $tpage['pageid'], $ARCHIVE_ALIVE, $TAG_OVERRIDE, $ARCHIVE_BY_ACCESSDATE, $TOUCH_ARCHIVE, $DEAD_ONLY, $NOTIFY_ERROR_ON_TALK, $NOTIFY_ON_TALK, $TALK_MESSAGE_HEADER, $TALK_MESSAGE, $TALK_ERROR_MESSAGE_HEADER, $TALK_ERROR_MESSAGE, $DEADLINK_TAGS, $CITATION_TAGS, $IGNORE_TAGS, $WAYBACK_TAGS, $WEBCITE_TAGS, $MEMENTO_TAGS, $ARCHIVEIS_TAGS, $ARCHIVE_TAGS, $IC_TAGS, $PAYWALL_TAGS, $VERIFY_DEAD, $LINK_SCAN, $NOTIFY_ON_TALK_ONLY, $MLADDARCHIVE, $MLMODIFYARCHIVE, $MLTAGGED, $MLTAGREMOVED, $MLFIX, $MLDEFAULT, $PLERROR, $MAINEDITSUMMARY, $ERRORTALKEDITSUMMARY, $TALKEDITSUMMARY, $tid)); if (LIMITEDRUN === true && is_int($debugStyle) && $debugStyle === $runpagecount) { break; } } $workerQueue->shutdown(); $workerQueue->collect(function ($thread) { global $pagesModified, $linksAnalyzed, $linksArchived, $linksFixed, $linksTagged; $stats = $thread->result; if ($stats['pagemodified'] === true) { $pagesModified++; } $linksAnalyzed += $stats['linksanalyzed']; $linksArchived += $stats['linksarchived']; $linksFixed += $stats['linksrescued']; $linksTagged += $stats['linkstagged'];
declare (ticks=1); // A function called on each tick event function tick_handler() { $name = 'log.txt'; $memory = memory_get_usage(); file_put_contents($name, "{$memory}\n", FILE_APPEND); } register_tick_function('tick_handler'); class WebWork extends Worker { private $num; public function __construct($num) { $this->num = $num; } public function run() { print "Run en webwork {$this->num}\n"; for ($a = 1; $a < 5; $a++) { $x = file_get_contents('http://adminwawas.webability.org:81'); print "Load en webwork {$this->num}::{$a} terminado\n"; $this->wait(); } print "End Run en webwork {$this->num}\n"; } } $pool = new Pool(100); for ($a = 1; $a < 200000; $a++) { $pool->submit(new WebWork($a)); }
/** * */ public function run() { // Reap the threads! $this->websocket->loop->addPeriodicTimer(600, function () { $this->log->addInfo('Restarting the threading pool, to clear out old threads..'); // Shutdown the pool $this->pool->shutdown(); $this->timers->shutdown(); // Startup the pool again $this->pool = new \Pool(count($this->onMessage), \Worker::class); $this->timers = new \Pool(count($this->onTimer), \Worker::class); }); // Handle the onReady event, and setup some timers and so forth $this->websocket->on('ready', function (Discord $discord) { $this->log->addInfo('Websocket connected..'); // Update our presence status $game = new Game(array('name' => $this->globalConfig->get('presence', 'bot', "table flippin'"), 'url' => null, 'type' => null), true); $this->websocket->updatePresence($game, false); // Count the amount of people we are available to.. /** @var Guild $guild */ foreach ($this->discord->getClient()->getGuildsAttribute()->all() as $guild) { $this->extras['memberCount'] += $guild->member_count; $this->extras['guildCount']++; $this->extras['guild']['memberCount']["id{$guild->id}"] = $guild->member_count; $this->extras['onMessagePlugins'] = $this->onMessage; $this->extras['onVoicePlugins'] = $this->onVoice; } $this->log->addInfo("Member count, currently available to: {$this->extras['memberCount']} people"); // Setup the timers for the timer plugins foreach ($this->onTimer as $command => $data) { $this->websocket->loop->addPeriodicTimer($data['timer'], function () use($data, $discord) { try { $plugin = new $data['class']($discord, $this->log, $this->globalConfig, $this->db, $this->curl, $this->settings, $this->permissions, $this->container->get('serverConfig'), $this->users, $this->extras); $this->timers->submit($plugin); } catch (\Exception $e) { $this->log->addError("Error running the periodic timer: {$e->getMessage()}"); } }); } // Issue periodically recounting and other things (Needed because of pthreads not putting the entire context into children - leading to some weirdness in some plugins) $this->websocket->loop->addPeriodicTimer(600, function () { $this->extras['memberCount'] = 0; $this->extras['guildCount'] = 0; /** @var Guild $guild */ foreach ($this->discord->getClient()->getGuildsAttribute()->all() as $guild) { $this->extras['memberCount'] += $guild->member_count; $this->extras['guildCount']++; $this->extras['guild']['memberCount']["id{$guild->id}"] = $guild->member_count; $this->extras['onMessagePlugins'] = $this->onMessage; $this->extras['onVoicePlugins'] = $this->onVoice; } // Output periodic information while doing the recounting stuff $this->log->addInfo('Currently running audio streams: ' . count($this->audioStreams)); $this->log->addInfo("Member recount, currently available to: {$this->extras['memberCount']} people"); }); // @todo run a timer to check if there are any active voice sessions - and if there are, if there are any people in those voice sessions // If not, stop the session and leave the channel (To save some bandwidth) }); $this->websocket->on('error', function ($error, $websocket) { $this->log->addError('An error occurred on the websocket', [$error->getMessage()]); die(1); }); $this->websocket->on('close', function ($opCode, $reason) { $this->log->addWarning('Websocket got closed', ['code' => $opCode, 'reason' => $reason]); die(1); }); $this->websocket->on('reconnecting', function () { $this->log->addInfo('Websocket is reconnecting..'); }); $this->websocket->on('reconnected', function () { $this->log->addInfo('Websocket was reconnected..'); }); // Handle incoming message logging $this->websocket->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) { $this->log->addInfo("Message from {$message->author->username}", [$message->content]); // Don't update data for ourselves.. if ($message->author->id !== $discord->getClient()->id) { $this->users->set($message->author->id, $message->author->username, 'online', null, date('Y-m-d H:i:s'), date('Y-m-d H:i:s'), $message->content); } // @todo Create text logs }); // Handle plugin running $this->websocket->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) { $guildID = $message->getChannelAttribute()->guild_id; // Get server config $config = $this->settings->get($guildID); // Is the person admin? $userDiscordID = $message->author->id; foreach ($this->globalConfig->get('admins', 'permissions') as $admins) { $message->isAdmin = $admins === $userDiscordID; } // Define the prefix if it isn't already set.. @($config->prefix = $config->prefix ?? $this->globalConfig->get('prefix', 'bot')); // Check if the user requested an onMessage plugin if (substr($message->content, 0, strlen($config->prefix)) === $config->prefix) { $content = explode(' ', $message->content); foreach ($this->onMessage as $command => $data) { $parts = []; foreach ($content as $index => $c) { foreach (explode("\n", $c) as $p) { $parts[] = $p; } } if ($parts[0] === $config->prefix . $command) { // If they are listed under the admins array in the bot config, they're the super admins if (in_array($message->author->id, $this->globalConfig->get('admins', 'permissions'))) { $userPerms = 3; } elseif (null !== $message->getChannelAttribute()->getGuildAttribute()->owner_id && $message->author->id === $message->getChannelAttribute()->getGuildAttribute()->owner_id) { $userPerms = 2; } else { $userPerms = 1; } if ($userPerms >= $data['permissions']) { try { $message->getChannelAttribute()->broadcastTyping(); if ($data['class'] === "\\Sovereign\\Plugins\\onMessage\\auth") { /** @var \Threaded $plugin */ $plugin = new $data['class']($message, $discord, $config, $this->log, $this->globalConfig, $this->db, $this->curl, $this->settings, $this->permissions, $this->container->get('serverConfig'), $this->users, $this->extras); $plugin->run(); } else { /** @var \Threaded $plugin */ $plugin = new $data['class']($message, $discord, $config, $this->log, $this->globalConfig, $this->db, $this->curl, $this->settings, $this->permissions, $this->container->get('serverConfig'), $this->users, $this->extras); $this->pool->submit($plugin); } $this->log->addInfo("{$message->author->username}#{$message->author->discriminator} ({$message->author}) ran command {$config->prefix}{$command}", $content); } catch (\Exception $e) { $this->log->addError("Error running command {$config->prefix}{$command}. Command run by {$message->author->username} in {$message->getChannelAttribute()->name}. Error: {$e->getMessage()}"); $message->reply("**Error:** There was a problem running the command: {$e->getMessage()}"); } } } } } }); // Handle joining a voice channel, and playing.. stuff.... $this->websocket->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) { // Get the guildID $guildID = $message->getChannelAttribute()->guild_id; // Get this guilds settings $config = $this->settings->get($guildID); // Get the prefix for this guild @($config->prefix = $config->prefix ?? $this->globalConfig->get('prefix', 'bot')); if (substr($message->content, 0, strlen($config->prefix)) === $config->prefix) { $content = explode(' ', $message->content); foreach ($this->onVoice as $command => $data) { $parts = []; foreach ($content as $index => $c) { foreach (explode("\n", $c) as $p) { $parts[] = $p; } } if ($parts[0] === $config->prefix . $command) { try { $voiceChannels = $message->getFullChannelAttribute()->getGuildAttribute()->channels->getAll('type', 'voice'); foreach ($voiceChannels as $channel) { if (!empty($channel->members[$message->author->id])) { $voice = new $data['class'](); $voice->run($message, $discord, $this->websocket, $this->log, $this->audioStreams, $channel, $this->curl); } } } catch (\Exception $e) { $this->log->addError("Error running voice command {$config->prefix}{$command}. Command run by {$message->author->username} in {$message->getChannelAttribute()->name}. Error: {$e->getMessage()}"); $message->reply("**Error:** There was a problem running the command: {$e->getMessage()}"); } } } } }); // Handle if it's a message for the bot (CleverBot invocation) $this->websocket->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) { // If we got highlighted we should probably answer back if (stristr($message->content, $discord->getClient()->id)) { try { $this->pool->submit(new cleverBotMessage($message, $discord, $this->log, $this->globalConfig, $this->db, $this->curl, $this->settings, $this->permissions, $this->container->get('serverConfig'), $this->users)); } catch (\Exception $e) { $message->reply("**Error:** There was an error with CleverBot: {$e->getMessage()}"); } } }); // Handle presence updates $this->websocket->on(Event::PRESENCE_UPDATE, function (PresenceUpdate $presenceUpdate) { if ($presenceUpdate->user->id && $presenceUpdate->user->username) { try { $this->log->addInfo("Updating presence info for {$presenceUpdate->user->username}"); $game = $presenceUpdate->getGameAttribute()->name ?? null; $this->users->set($presenceUpdate->user->id, $presenceUpdate->user->username, $presenceUpdate->status, $game, date('Y-m-d H:i:s'), null, null); } catch (\Exception $e) { $this->log->addError("Error: {$e->getMessage()}"); } } }); // Create a new cleverbot \nick\ for this new guild $this->websocket->on(Event::GUILD_CREATE, function (Guild $guild) { $cleverBotExists = $this->db->queryField("SELECT serverID FROM cleverbot WHERE serverID = :serverID", "serverID", array(":serverID" => $guild->id)); $guildExists = $this->db->queryField("SELECT guildID FROM guilds WHERE guildID = :serverID", "guildID", array(":serverID" => $guild->id)); // Only create a new server nick if the cleverbot instance doesn't exist.. (Hopefully cleverbot.io is done deleting them at random) if (!isset($cleverBotExists)) { $this->log->addInfo("Setting up Cleverbot for {$guild->name}"); $serverID = $guild->id; $result = $this->curl->post('https://cleverbot.io/1.0/create', ['user' => $this->globalConfig->get('user', 'cleverbot'), 'key' => $this->globalConfig->get('key', 'cleverbot')]); if ($result) { $result = @json_decode($result); $nick = $result->nick ?? false; if ($nick) { $this->db->execute('INSERT INTO cleverbot (serverID, nick) VALUES (:serverID, :nick) ON DUPLICATE KEY UPDATE nick = :nick', [':serverID' => $serverID, ':nick' => $nick]); } } } if (!isset($guildExists)) { $this->db->execute("INSERT IGNORE INTO guilds (guildID) VALUES (:guildID)", array(":guildID" => $guild->id)); // Send a hello message to the channel (Only if it's new!) //$message = "Hello, i was invited here by someone with admin permissions, i have quite a few features that you can discover by doing %help\n"; //$message .= "I am sorry if i am triggering other bots aswell, you can change my trigger with %config setTrigger newTrigger (Example: %config setTrigger *)\n"; //$message .= "If you for some reason don't want me here after all, just kick me ;)"; // Get the first channel in the list (usually the default channel) //$channel = $guild->channels->first(); //$channel->sendMessage($message); } }); // Run the websocket, and in turn, the bot! $this->websocket->run(); }
<?php class ClosureRunner extends Threaded { public function __construct($closure) { $this->closure = $closure; } public function run() { $closure = $this->closure; $closure(); } } $foo = 'test'; $pool = new Pool(5, Worker::class); $pool->submit(new ClosureRunner(function () use($foo) { var_dump($foo); })); $pool->shutdown(); // Passing example ////////////////////////////////////////////////////////////////////// $pool = new Pool(5, Worker::class); $foo = 'test'; $pool->submit(Collectable::from(function () use($foo) { var_dump($foo); $this->setGarbage(); })); $pool->shutdown();