Hi Clive,

Thanks for the answer. I found 2 things:
 $client->set_identity = $plugin->config->{identity} . "-$$"; should be  $client->set_identity($plugin->config->{identity} . "-$$");
- Using builders for the properties doesn't work, I've to use BUILD as you suggested.

Now I've this:

package Dancer2::Plugin::ZMQ;

use Dancer2::Plugin;

our $version = '0.01';

use ZMQ::FFI;
use ZMQ::FFI::Constants qw(ZMQ_REQ);

has _context => (is => 'rw');
has _client => (is => 'rw', plugin_keyword => 'zmq');

sub BUILD {
    my $plugin = shift;
    my $args = shift;

    $plugin->_context(ZMQ::FFI->new());
    $plugin->_client($plugin->_context->socket(ZMQ_REQ));
    $plugin->_client->set_identity($plugin->config->{identity} . "-$$");
    $plugin->_client->connect($plugin->config->{host});
}

1;


This works if you run the dancer app as a standalone process. If I run it with Starman that initialises several workers, it doesn't work as it tries to share the same instance between all the workers (you can't share ZMQ context between processes/threads).
Is there any way to create one instance per process?

Regards,
Alfonso.

On Fri, Oct 13, 2017 at 4:32 PM, Clive Eisen <clive@hildebrand.co.uk> wrote:
I do a very similar thing for a custom redis plugin I wrote

You have to declare the object outside the BUILD and set it inside

eg
package Dredis;
use Redis::Fast;
use Dancer2::Plugin;

my $redii;

sub BUILD {
        my ($plugin) = @_;
<snip lots of setup stuff>
$redii->{$r}{$i} = Redis::Fast->new( %opts );
}

Then use $redi-> in the get/set methods
eg
sub dredis {
        my( $called, $plugin, $method, @args ) = @_;
        
        return $redii->{$called}->$method(@args);
}
1;

--
Clive Eisen
GPG: 75056DD0






On 13 Oct 2017, at 14:29, Alfonso Pinto <alfonso.pinto@gmail.com> wrote:

Dear all,

I'm trying to write a Dancer2::Plugin to maintain ZMQ socket and send some information to a backend when a request is received.

This is the plugin :

package Dancer2::Plugin::ZMQ;


use Dancer2::Plugin;


use ZMQ::FFI;

use ZMQ::FFI::Constants qw(ZMQ_REQ);


has host => (is => 'ro');

has identity => (is => 'ro');


has _context => (is => 'ro', lazy_build => 1);

sub _build_context {

    my $plugin = shift;

    return ZMQ::FFI->new();

}


has client => (is => 'ro', lazy_build => 1, plugin_keyword => 'zmq');

sub _build_client {

    my $plugin = shift;


    my $client = $plugin->_context->socket(ZMQ_REQ);

    $client->set_identity = $plugin->config->{identity} . "-$$";

    $client->connect($plugin->config->{host});

    return $client;

}


1;

 
 This is my config.yml:

plugins:
    ZMQ:
        identity: "api-gw"
        host: "tcp://proxy:6660"


And this is how I use it in one route:

post '/' => sub {
    my $message = body_parameters->get('message');
    zmq->send(message =>$message);
    my $reply = zmq->recv();
    return {"reply" => $reply};
};
 

The issue is that I get this error:
Router exception: Can't call method "send" on an undefined 
 
I don't understand why it's not keeping the client instantiated. What is wrong withmy approach? What I don't want is to create a socket for each request received.

And before someone asks, the backend is working and replying. A simple script like this one works in my setup:

use v5.10;
use ZMQ::FFI qw(ZMQ_REQ);
 
my $endpoint = "tcp://proxy:6660";
my $ctx      = ZMQ::FFI->new();
 
my $s1 = $ctx->socket(ZMQ_REQ);
$s1->connect($endpoint);
 
$s1->send('ohhai');
print $s1->recv();

Thanks in advance.
Regards,
Alfonso 
_______________________________________________
dancer-users mailing list
dancer-users@dancer.pm
http://lists.preshweb.co.uk/mailman/listinfo/dancer-users


_______________________________________________
dancer-users mailing list
dancer-users@dancer.pm
http://lists.preshweb.co.uk/mailman/listinfo/dancer-users