# Support for init method on service

**URL:** <https://discourse.nameko.io/t/support-for-init-method-on-service/285>\
**Category:** Github Issues\
**Created:** [August 13, 2018, 9:33am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285 "2018-08-13T09:33:13Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 13, 2018, 9:33am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/1 "2018-08-13T09:33:13Z")

</div>

_From @rizplate on Thu Mar 29 2018 21:56:23 GMT+0000 (UTC)_  
  
Can the nameko framework call an init\_service method on service, where we can initialize some variables? or do we have to create extensions/dependancies  
  
_Copied from original issue: [https://github.com/nameko/nameko/issues/529](https://github.com/nameko/nameko/issues/529)_

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 13, 2018, 9:33am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/2 "2018-08-13T09:33:17Z")

</div>

_From @mattbennett on Wed Apr 25 2018 15:36:57 GMT+0000 (UTC)_  
  
Sorry for the slow response to this @rizplate. The answer is that you have to create extensions to do this.

Nameko service classes are instantiated for every worker and discarded afterwards. That means if you save some state to `self.whatever` in one method, it won’t be there when the next worker executes. You should use dependency providers to manage state between workers.

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 8:22am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/3 "2019-08-25T08:22:00Z")

</div>

> [@mattbennett](#):
>
> That means if you save some state to `self.whatever` in one method, it won’t be there when the next worker executes. You should use dependency providers to manage state between workers.

Hi Matt,

I thought I had this sorted. I have a connect dependency for determining a connection, and then keeping it open. I understood that a dependency provider ` __init__ `, only executed once, when the service was started, and then retained state between worker call. So I have a `self.connected` value and a `self.connectionString` and a piece of logic like this:

```
if not self.connected:
    self.connectionString=self.connect()
    self.connected=1
return self.connectionString

```

And it always seems to do `self.connect()`

Do I need to post more code, or have I completely misunderstood this?

Regards

Steve

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 25, 2019, 11:29am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/4 "2019-08-25T11:29:32Z")

</div>

> I understood that a dependency provider ` __init__ ` , only executed once, when the service was started

`DependencyProvider.setup()` and `start()` are only executed once, at service startup time.

` __init__ ()` is actually called twice though – once at class declaration time and once when the service class is bound to a container. [See the note here](https://nameko.readthedocs.io/en/stable/writing_extensions.html?highlight=bind#structure) about avoiding side-effects in that method.

You probably want to move your connection code into `DependencyProvider.setup()`. Does this explain the behaviour you’re seeing?

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 11:36am UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/5 "2019-08-25T11:36:54Z")

</div>

So any variables either global variables defined under the `class` statement or as `self.var` will persist across worker calls. Is that correct? If that is not happening then it’s a bug.

I’ll try it with `.setup()` and `start()` as well to see if it makes any difference.

If there is still a problem, I’ll start a new thread.

Thanks.

Steve.

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 25, 2019, 1:08pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/6 "2019-08-25T13:08:16Z")

</div>

> any variables either global variables defined under the `class` statement or as `self.var` will persist across worker calls. Is that correct?

On the `DependencyProvider`? It is persisted, but the worker does not get access to the `DependencyProvider` instance, only what is returned from `DependencyProvider.get_dependency()`. If `get_dependency()` returns `self` you’ll get the behaviour you want.

Note that returning `self` is not best practice though. The value of the dependency injection pattern is in the layer of abstraction between the _dependency provider_ and the functional part that the service actually needs. Think of the difference between code that maintains a connection pool, and the connection object itself; the pool belongs in the provider, whereas the service only needs access to a single connection.

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 1:10pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/7 "2019-08-25T13:10:04Z")

</div>

> [@mattbennett](#):
>
> On the `DependencyProvider` ? It is persisted, but the worker does not get access to the `DependencyProvider` instance, only what is returned from `DependencyProvider.get_dependency()` . If `get_dependency()` returns `self` you’ll get the behaviour you want.

Does it have to be named `DependencyProvider.get_dependency()`?

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 1:13pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/8 "2019-08-25T13:13:24Z")

</div>

Actually, I have a series of calls to the dependency provider:

```
connect()
write(a)
readline()
disconnect()
getstatus()

```

and one or two others.

My dependencyprovider really does the work, and the worker just passes the parameter to it.

The connection object stays in dependency provider (because I don’t know how to serialise it) and I just pass stuff to it. Actually also because there is an overhead to connecting and I want to save on this overhead.

Regards

Steve.

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 25, 2019, 1:17pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/9 "2019-08-25T13:17:11Z")

</div>

Please post your code, or a simplified version. Not sure what you mean from just the description.

Have you read [the docs on creating dependency providers](https://nameko.readthedocs.io/en/stable/writing_extensions.html#writing-dependency-providers)?

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 1:29pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/10 "2019-08-25T13:29:15Z")

</div>

Here’s my test code. It works if called from a shell on another machine, but it always reconnects.

Yes, I read the docs, but I think they’ve changed a lot from when I last saw them.

Here’s the code:

```
#!/usr/bin/env python

import subprocess
import serial # For Arduino comms: python2.7 -m pip install pyserial
import time

from nameko.rpc import rpc, RpcProxy
from nameko.extensions import DependencyProvider

class USBConnection(DependencyProvider):
    name = "Connection_service"
    
    def __init__ (self):
        self.portList2=[]
        if not hasattr(self, "connected"):
            self.portList2 = self.getPorts()
            if len(self.portList2):
                port = self.getPort()
                self.ser = self.connect(port)
            else:
                print "004 USB - No serial device found)"
        else:
            print "006 USB already connected...)"
    
    @rpc
    def getPorts(self):
    
        batcmd='ls /dev/tty*'
        portList = subprocess.check_output(batcmd, shell=True)
        portList= portList.splitlines()
        # Look for serial ports of format "ttyUSBn"
        portList2 = []
        for x in portList:
            if u'ttyUSB' in x.decode('utf-8'):
                portList2.append(x)
        
        print ("008 USB getPorts: %s") % portList2
        return portList2

    @rpc
    def getPort(self, port=0):
        
        if len(self.portList2):
            port = str(self.portList2[port].decode("utf-8"))
            print ("010 USB getPort: %s") % port
            self.ser=1
        else:
            error= u'USB not connected'
            print ("020 USB getPort: %s\n") % error
            self.err = "1"
            self.ser=0
            
        return port
    
    @rpc
    def connect(self, port):
        print ("100 USB connecting: %s") % port
        try:
            self.conn = serial.Serial(port,9600, timeout=0) #, parity=serial.PARITY_NONE)
            time.sleep(2)  
            self.error=""
            self.ser=1
            self.connected=1
        except:
            print("130 USB connect: %s\n") % "Connect failed"
            self.ser=0
            self.connected=0
            
        return self.ser
        
    @rpc
    def write(self,A_Command):
        
        print ("210 USB write: ", self.conn, "\n")
        print ("220 USB write USBConnection '%s'" % A_Command.encode('utf-8'))
        try:
            self.conn.write(A_Command)# .encode('utf-8'))
        except:
            errMsg = "230 USB write '%s' command failed." % A_Command.encode('utf-8')
            print (errMsg)
            self.connected=0
    
    @rpc
    def writeDelayed(self,delaySecs, B_Command):
        
        time.sleep(delaySecs)
        # Clear Buffers
        self.conn.flush()
        self.conn.reset_input_buffer()
        self.conn.reset_output_buffer()
        print ("300 USB write USBConnection '%s'" % B_Command.encode('utf-8'))
        try:
            self.conn.write(A_Command.encode('utf-8'))
        except:
            errMsg = "310 USB write '%s' command failed." % B_Command.encode('utf-8')
            print (errMsg)
            connected=0
    
    @rpc
    def readline(self,A_Command):
        time.sleep(2) # wait for Arduino
        print ("405 USB readline: ", self.conn)
        try:
            self.conn.write(A_Command.encode('utf-8'))
            print ("410 USB written '%s' command." % A_Command.encode('utf-8'))
        except:
            print ("420 USB write '%s' command failed." % A_Command.encode('utf-8'))
            self.connected=0
        
        time.sleep (.4)
        a=""
        try:
            self.printConn()
            a= self.conn.readline() #.decode("utf-8") #.strip('\n').strip('\r')
            print ("430 USB readline: '%s'." % a.strip('\n').strip('\r'))
        except:
            errMsg = "440 USB readline command failed."
            print (errMsg)
            a= "read error"
        return a.strip('\n').strip('\r')
    
    @rpc
    def printConn(self):
        print (self.conn)
        return
    
class Arduino(object):
    
    name = "Arduino_service"
    usb = RpcProxy("Connection_service")
    reporting=0
    ser=0
    
    # Initialise Arduino
    @rpc
    def connect(self):
        print ("000 Arduino connect: %s\n") % "started"
        # List serial ports
        
        portList2 = self.usb.getPorts()
        if len(portList2):
            port = str(portList2[0].decode("utf-8"))
            print ("010 Arduino connect: %s\n") % port
            self.usb.connect(port)
            self.ser=1
        else:
            error= u'Arduino not connected'
            print ("020 Arduino connect: %s\n") % "Arduino NOT connected\n"
            self.ser=0

        return self.ser
    @rpc        
    def write(self,A_Command):
        if not self.usb.connected:
            print "100 Arduino Connecting..."
            self.connect()
        else:
            print "110 Arduino Connected..."
        print ("120 Arduino write '%s'" % A_Command)
        errMsg=""
        try:
            self.usb.write(A_Command)
        except:
            errMsg = "130 Arduino write '%s' command failed." % A_Command
            print (errMsg)
    
        return json.dumps(errMsg)
    @rpc
    def readline(self, A_Command):
        if not self.usb.connected:
            print "200 Arduino Connecting..."
            self.connect()
        else:
            print "210 Arduino Connected..."
        print ("220 Arduino read usb: %s" ) % A_Command
        try:
            return self.usb.readline(A_Command) #.decode("utf-8").strip('\n').strip('\r')
        except:
            errMsg = "230 Arduino readline command failed."
            print (errMsg)
            return "read error"
    
    @rpc
    def readline2(self, A_Command):
        
        ser = serial.Serial("/dev/ttyUSB1",9600, timeout=.1) # open first serial port
        print ser.portstr # check which port was really used

        time.sleep(4)   
        ser.write(A_Command.encode('utf-8')) # write a string
        time.sleep(1)
        a=ser.readline()
        ser.close() # close port
        return a.strip('\n').strip('\r')
    
    @rpc
    def disconnect(self):
        try:
            Arduino.ser.write(b'DISCONNECT#')
            print ("300 Arduino Disconnected")
        except:
            errMsg = "Arduino write 'DISCONNECT#' command failed."
            if Arduino.reporting:
                Arduino.Log.AppendText( " " + str(errMsg) + "\n$")
            else:
                print (errMsg)
    @rpc
    def printConn(self):
        self.usb.printConn ()
        
    @rpc
    def connStatus(self):
        return self.usb.connected
```

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 25, 2019, 1:58pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/11 "2019-08-25T13:58:14Z")

</div>

This is very broken I’m afraid.

Your `USBConnection` class is extending `DependencyProvider` but being used like a service. DependencyProviders don’t have entrypoints like `@rpc`.

Suggest you study a simple example like those in [https://github.com/nameko/nameko-examples](https://github.com/nameko/nameko-examples) to get a better idea. In particular, note how the [Products service](https://github.com/nameko/nameko-examples/blob/master/products/products/service.py) uses the [Storage dependency](https://github.com/nameko/nameko-examples/blob/master/products/products/dependencies.py) to interact with Redis.

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 25, 2019, 3:46pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/12 "2019-08-25T15:46:23Z")

</div>

> [@mattbennett](#):
>
> This is very broken I’m afraid.

Thanks for saying it like it is.

I’ve not used Redis before. It seems to be a bit like a ram-disk. Is that right? And it’s one of the ways that the dependency info persists between calls. The others being databases or files.

So If I look at the example you gave, the steps are as follows:

1. The app calls, eg,  
`@rpc`  
`def get(self, product_id):`  
`product = self.storage.get(product_id)`  
`return schemas.Product().dump(product).data`
2. Which calls:  
` storage.get`  
But `get` is part of `StorageWrapper`. How do they connect? They don’t seem to be descended from one another.

Regards

Steve

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 27, 2019, 7:26pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/13 "2019-08-27T19:26:57Z")

</div>

`StorageWrapper` is the object returned by `get_dependency`.

This is Nameko’s dependency injection in action. The `Storage` DepedencyProvider is what is declared on the Products service class, but what is actually injected into the service when a worker fires is an instance of whatever is returned from `Storage.get_dependency` – in this case an instance of `StorageWrapper`.

This pattern allows you to keep the logic of maintaining connections (in this case just the creation of the client in `Storage.setup()`) separate from the logic of using those connections (in this case everything in `StorageWrapper`).

---

<div class="post-metadata">

**Author:** ![SteveBz](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/stevebz/32/38_2.png) [@SteveBz](https://discourse.nameko.io/u/SteveBz)\
**Post date:** [August 31, 2019, 3:35pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/14 "2019-08-31T15:35:55Z")

</div>

Hi Matt,

OK, well I really didn’t get that paradigm. I’ve searched “Dependency Injection” on Google and it’s a lot clearer. Anyhow, I’ve implemented it and it works beautifully. It’s much faster and much more error free.

I’ll try to post my code as sample code later.

Regards

Steve.

---

<div class="post-metadata">

**Author:** ![mattbennett](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.nameko.io/mattbennett/32/13_2.png) [@mattbennett](https://discourse.nameko.io/u/mattbennett)\
**Post date:** [August 31, 2019, 8:33pm UTC](https://discourse.nameko.io/t/support-for-init-method-on-service/285/15 "2019-08-31T20:33:22Z")

</div>

Excellent, very pleased to hear that!
