[dancer-users] Problems writing a Plugin

Clive Eisen clive at hildebrand.co.uk
Fri Oct 13 19:11:56 BST 2017


Do it the way I did it with a my variable outside to hold your handler. Then you will get one per child (well i do anyway)

--
Clive

> On 13 Oct 2017, at 19:07, Alfonso Pinto <alfonso.pinto at gmail.com> wrote:
> 
> 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 at 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 at 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 at dancer.pm
>>> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>> 
>> 
>> _______________________________________________
>> dancer-users mailing list
>> dancer-users at dancer.pm
>> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
>> 
> 
> _______________________________________________
> dancer-users mailing list
> dancer-users at dancer.pm
> http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.preshweb.co.uk/pipermail/dancer-users/attachments/20171013/80da78de/attachment.html>


More information about the dancer-users mailing list