[rt-devel] kanben view in RT 4.2.12
Joachim Schiele
js at lastlog.de
Thu Feb 25 21:24:28 EST 2016
On 25.02.2016 23:29, Joachim Schiele wrote:
>>> - where in the RT code would be the best place to add the WEBSOCKET REST
>>> extension (into the routing) + it needs an main loop waiting for
>>> 'ticket'-table changes
>>
>> You’ll probably want to use Plack::App::WebSocket with an event-based PSGI server (probably Twiggy). RT is typically deployed with FastCGI or similar, so you have your work cut out for you there. :) You’ll either want to have good documentation around switching an RT deployment from FastCGI to Twiggy, or have your users deploy a standalone Twiggy server alongside their RT http server.
>
> hm. this leaves me with three more questions:
>
> - could you please point out what i need to do in order to use twiggy
> instead of 'the usual' deployment method?
right now i call the server like this:
plackup /tmp/rt4/opt/rt4/sbin/standalone_httpd --port 8080
Twiggy: Accepting connections at http://0.0.0.0:8080/
...
so this is probably answered now. can i run the server like this in
production?
i had a lengthily discussion about this on irc#perl:
(23:56) < mst> well, you could run the two side by side
(23:56) < mst> you should be running two daemons anyway
(23:56) < mst> you don't want your websocket handler in the same
process as the main RT code
as well as:
(23:58) < hobbs> yeah. Even if you switch the server, RT will do all
kinds of things that will jam up the loop and make your websockets useless
(23:58) < hobbs> or at least perform very badly
any comment on using 'plack' instead of 'psgi'/'fcgi' with websockets
implemented like shown in Plack::App::WebSocket?
> regarding WS:
> i've been playing with Plack::App::WebSocket a lot. mainly with this
> example:
> https://github.com/motemen/Plack-Middleware-WebSocket/blob/master/eg/echo/app.psgi
>
> and i'm currently having trouble with two things:
>
> - how to extend the example to do a mysql query every second and then
> send data to all clients (i extended the example so every incoming
> string is sent to _all_ clients already)?
>
> something like this:
> my $w = AnyEvent->timer (after => 3, cb => sub { foo });
>
> but without this:
> AnyEvent::Loop::run;
> the timer will never be executed. and if i start the loop with the
> above code the webserver won't be spinning.
>
> - looking into the rt-extension-rest2 i wonder how to put the above
> example code into
> https://github.com/bestpractical/rt-extension-rest2/blob/943d8f69ef8e1a0e6d6615fc4f92df0d3fde3cf2/lib/RTx/REST.pm
got that working, too. was actually pretty simple:
i just had to add a mount "/websocket" like this:
# Called by RT::Interface::Web::Handler->PSGIApp
sub PSGIWrap {
print STDERR "REST2.pm: qknight was here: sub PSGIWrap", "\n\n";
my ($class, $app) = @_;
return builder {
mount $REST_PATH => $class->to_app;
mount '/' => $app;
mount "/websocket" => Plack::App::WebSocket->new(
on_error => sub {
my $env = shift;
print STDERR "plack_app_websocket.psgi: qknight was here:
/websocket on_error", "\n\n";
return [500,
["Content-Type" => "text/plain"],
["Error: " .
$env->{"plack.app.websocket.error"}]];
},
on_establish => sub {
print STDERR "plack_app_websocket.psgi: qknight was here:
/on_established", "\n\n";
my $conn = shift; ##
Plack::App::WebSocket::Connection object
my $env = shift; ## PSGI env
push(@WSConnections, $conn);
$conn->on(
message => sub {
my ($conn, $msg) = @_;
print STDERR "plack_app_websocket.psgi: qknight was here:
message: $msg", "\n\n";
foreach (@WSConnections) {
$_->send($msg);
}
},
finish => sub {
# most epic remove function ever OMFG
(qknight)
my @l;
foreach(@WSConnections) {
if ($_ != $conn) {
push(@l, $_)
}
}
@WSConnections = @l;
undef $conn;
warn "Bye!!\n";
},
);
}
)->to_app;
};
}
since my @WSConnections; is a global object i can now send messages to
all attached clients **yay**!
with using a singleton, like shown here:
http://search.cpan.org/~abw/Class-Singleton-1.03/Singleton.pm#DERIVING_SINGLETON_CLASSES
i should be able to create a perl based WSClass which can be used from
all the RT-codebase as:
- Instrumenting RT::Record::Create and
- RT::Record::_Set generally, or
- RT::Ticket::Create and
- RT::Ticket::_Set specifically
as you pointed out in order to circumvent the MySQL-only solution.
>>> - how to make this a general solution: instead of binding this feature
>>> to MYSQL we could also extend the ticket API with various callbacks on:
>>> - add/remove/update ticket functionality
>>
>> Instrumenting RT::Record::Create and RT::Record::_Set generally, or RT::Ticket::Create and RT::Ticket::_Set specifically, should get you most of the way there.
>
> that is very good information! but i would have to 'modify' the RT-Core
> as this can't be done from an extension, right?
>
>>> === /the question ===
>>>
>>> we plan to release the kanban as open source once we are done with the
>>> implementation.
>>>
>>> if you could help us out with implementation details, that'd be a delight.
>>
>> Absolutely! This is the best forum for such conversations. :)
>
> very good!
>
>>> thanks in advance,
>>> joachim & paul
>>
>> Thanks!
>> Shawn
>
> thanks very much for your help! it really is appreciated.
>
>
>
> ---------
> RT 4.4 and RTIR Training Sessions (http://bestpractical.com/services/training.html)
> * Hamburg Germany - March 14 & 15, 2016
> * Washington DC - May 23 & 24, 2016
>
More information about the rt-devel
mailing list