[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
so this is probably answered now. can i run the server like this in

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: " .
                    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);
                            message => sub {
                                my ($conn, $msg) = @_;
        print STDERR "plack_app_websocket.psgi: qknight was here:
message: $msg", "\n\n";
                                foreach (@WSConnections) {
                            finish => sub {
                                # most epic remove function ever OMFG
                                my @l;
                                foreach(@WSConnections) {
                                  if ($_ != $conn) {
                                    push(@l, $_)
                                @WSConnections = @l;
                                undef $conn;
                                warn "Bye!!\n";

since my @WSConnections; is a global object i can now send messages to
all attached clients **yay**!

with using a singleton, like shown here:

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