Stardust
view release on metacpan or search on metacpan
lib/Stardust.pm view on Meta::CPAN
182183184185186187188189190191192193194195196197198199200201202
}
}
},
),
# Message - [public]
# This controller emits a stream of messages to long-polling clients.
C(
Message
=> [
'/channel/([\w+]+)/stream/([.\d]+)'
],
get
=>
sub
{
warn
"coro [$Coro::current]"
if
$CONFIG
{debug};
my
(
$self
,
$channels
,
$client_id
) =
@_
;
my
$input
=
$self
->input;
my
$cr
=
$self
->cr;
my
@ch
=
split
(/\+/,
$channels
);
my
$last
=
time
;
while
(1) {
# Output
warn
"top of loop"
if
$CONFIG
{debug};
my
@messages
=
grep
{
defined
}
lib/Stardust.pm view on Meta::CPAN
205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
warn
"printing..."
.encode_json(\
@messages
)
if
$CONFIG
{debug};
$cr
->
(encode_json(\
@messages
));
};
$x
->
join
;
$last
=
time
;
# Hold for a brief moment until the next long poll request comes in.
warn
"waiting for next request"
if
(
$CONFIG
{debug});
$cr
->
next
;
# Start 1 coro for each channel we're listening to.
# Each coro will have the same Coro::Signal object, $activity.
my
$activity
= Coro::Signal->new;
my
@coros
=
map
{
my
$ch
= channel(
$_
);
async {
$ch
->signal->
wait
;
$activity
->broadcast };
}
@ch
;
# When running this behind a reverse proxy,
# it's useful to timeout before your proxy kills the connection.
push
@coros
, async {
my
$timeout
= Coro::Timer::timeout
$CONFIG
{timeout};
while
(not
$timeout
) {
Coro::schedule;
}
warn
"timeout\n"
if
$CONFIG
{debug};
$activity
->broadcast;
};
# The first coro that does $activity->broadcast wins.
warn
"waiting for activity on any of (@ch); last is $last"
if
$CONFIG
{debug};
$activity
->
wait
;
# Cancel the remaining coros.
for
(
@coros
) {
$_
->cancel }
}
},
continuity
=> 1,
),
);
1;
__END__
( run in 0.228 second using v1.01-cache-2.11-cpan-2b0bae70ee8 )