Skip to content

Commit

Permalink
add option to pass context to file_uri, various bug fixes found whe…
Browse files Browse the repository at this point in the history
…n adding `fileUri.php` example
  • Loading branch information
TheTechsTech committed Mar 11, 2020
1 parent 6cb195a commit 8fb6868
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 6 deletions.
5 changes: 3 additions & 2 deletions Coroutine/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -691,12 +691,13 @@ function file_exist($path)
* - This function needs to be prefixed with `yield`
*
* @param string $url
* @param resource|array|null $context
*
* @return resource
*/
function file_uri(string $url)
function file_uri(string $url, $contexts = null)
{
return FileSystem::open($url, 'r');
return FileSystem::open($url, 'r', 0, $contexts);
}

/**
Expand Down
45 changes: 42 additions & 3 deletions Coroutine/FileSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ final class FileSystem
'c+' => \UV::O_RDWR | \UV::O_CREAT,
);

protected static $fileOpenUriContext = [
'http' => [
'method' => 'GET',
'protocol_version' => '1.1',
'follow_location' => 1,
'request_fulluri' => false,
'max_redirects' => 10,
'ignore_errors' => true,
'timeout' => 1,
'user_agent' => 'Symplely Coroutine',
'headers' => [
'Accept' => '*/*'
],
],
'ssl' => [
'disable_compression' => true
]
];

/**
* Flag to control `UV` file operations.
*
Expand Down Expand Up @@ -864,8 +883,10 @@ function ($out_fd, $result) use ($task, $coroutine) {
* to the end of file. The file is created if it does not exist.
* - "`x+`" `Read/Write`: Creates a new file. Returns `FALSE` and an error if file already exists.
* - "`c+`" Open the file for reading and writing; otherwise it has the same behavior as "`c`".
* @param int $mode — this should be UV::S_IRWXU and some mode flag, `libuv` only.
* @param resource|array|null $contexts not for `libuv`.
*/
public static function open(string $path, string $flag, int $mode = \UV::S_IRWXU)
public static function open(string $path, string $flag, int $mode = \UV::S_IRWXU, $contexts = null)
{
if (isset(self::$fileFlags[$flag])) {
if (self::useUvFs() && (\strpos($path, '://') === false)) {
Expand All @@ -888,8 +909,20 @@ function ($stream) use ($task, $coroutine) {
}

return new Kernel(
function (TaskInterface $task, CoroutineInterface $coroutine) use ($path, $flag) {
$resource = @\fopen($path, $flag . 'b');
function (TaskInterface $task, CoroutineInterface $coroutine) use ($path, $flag, $contexts) {
$ctx = null;
if (\strpos($path, '://') !== false || \is_array($contexts)) {
$ctx = \stream_context_create(\array_merge(self::$fileOpenUriContext, (array) $contexts));
} elseif (\is_resource($contexts)) {
$ctx = $contexts;
}

if (\is_resource($ctx)) {
$resource = @\fopen($path, $flag . 'b', false, $ctx);
} else {
$resource = @\fopen($path, $flag . 'b');
}

if (\is_resource($resource)) {
\stream_set_blocking($resource, false);
}
Expand Down Expand Up @@ -1024,6 +1057,9 @@ protected static function closeFile($fd)
*/
public static function close($fd)
{
if (!\is_resource($fd))
return false;

if (self::useUvFs() && (self::meta($fd, 'wrapper_type') !== 'http')) {
return new Kernel(
function (TaskInterface $task, CoroutineInterface $coroutine) use ($fd) {
Expand Down Expand Up @@ -1057,6 +1093,9 @@ function (bool $bool) use ($task, $coroutine) {
*/
public static function meta($fd, ?string $info = null)
{
if (!\is_resource($fd) && $info == 'status')
return 400;

$meta = [];
if (\is_resource($fd)) {
$meta = \stream_get_meta_data($fd);
Expand Down
4 changes: 3 additions & 1 deletion Coroutine/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,9 @@ public static function shutdown(int $skipTask = 1)
function (TaskInterface $task, CoroutineInterface $coroutine) use ($skipTask) {
$tasks = $coroutine->currentTask();
$coroutine->shutdown($skipTask);
$coroutine->schedule($tasks[$skipTask]);
if (isset($tasks[$skipTask])) {
$coroutine->schedule($tasks[$skipTask]);
}
}
);
}
Expand Down
65 changes: 65 additions & 0 deletions examples/fileUri.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
include 'vendor/autoload.php';

/**
* Converted example of https://github.com/jimmysong/asyncio-examples from:
* @see https://youtu.be/qfY2cqjJMdw
*/
function get_statuses($websites)
{
$statuses = ['200' => 0, '400' => 0, '405' => 0];
$tasks = [];
foreach ($websites as $website) {
$tasks[] = yield \away(\get_website_status($website));
}

$taskStatus = yield \gather($tasks);
foreach ($taskStatus as $id => $status) {
if (!$status)
$statuses[$status] = 0;
else
$statuses[$status] += 1;
}

return \json_encode($statuses);
}

function get_website_status($url)
{
$id = yield \get_task();
$fd = yield \file_uri($url);
$status = \file_meta($fd, 'status');
yield \file_close($fd);
//[$meta, $status, $retry] = yield \head_uri($url);
print "task: $id, url: $url code: $status" . EOL;
return yield $status;
}

function lapse()
{
$i = 0;
while (true) {
echo '.';
$i++;
if ($i == 800) {
yield \shutdown();
}

yield;
}
}

function main()
{
yield \away(\lapse());
$websites = yield \file_file(__DIR__ . \DS . 'list_many.txt');
if ($websites !== false) {
$t0 = \microtime(true);
$data = yield get_statuses($websites);
$t1 = \microtime(true);
print $data . EOL;
print("getting website statuses took " . (float) ($t1 - $t0) . " seconds");
}
}

\coroutine_run(\main());
31 changes: 31 additions & 0 deletions examples/list_many.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
https://facebook.com/
https://twitter.com/
https://google.com/
https://youtube.com/
https://linkedin.com/
https://instagram.com/
https://pinterest.com/
https://blogspot.com/
https://wordpress.com/
https://apple.com/
https://tumblr.com/
https://vimeo.com/
https://godaddy.com/
https://yahoo.com/
https://flickr.com/
https://microsoft.com/
https://dell.com/
https://nytimes.com/
https://blogger.com/
https://soundcloud.com/
https://digg.com/
https://feedburner.com/
https://stumbleupon.com/
https://github.com/
https://parallels.com/
https://cnn.com/
https://paypal.com/
https://creativecommons.org/
https://imdb.com/
https://huffingtonpost.com/
https://espn.com/

0 comments on commit 8fb6868

Please sign in to comment.