Completed
Push — master ( d75605...cff8bf )
by Thomas
12:23
created

Outgoing.establish()   C

Complexity

Conditions 10

Size

Total Lines 33
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 27
nop 1
dl 0
loc 33
rs 5.9999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like exabgp.reactor.network.outgoing.Outgoing.establish() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import time
2
3
from exabgp.vendoring import six
4
5
from exabgp.protocol.family import AFI
6
from .connection import Connection
7
from .tcp import create,bind
8
from .tcp import connect
9
from .tcp import MD5
10
from .tcp import nagle
11
from .tcp import TTL
12
from .tcp import TTLv6
13
from .tcp import asynchronous
14
from .tcp import ready
15
from .error import NetworkError
16
17
18
class Outgoing (Connection):
19
	direction = 'outgoing'
20
21
	def __init__ (self, afi, peer, local, port=179,md5='',md5_base64=False, ttl=None):
22
		Connection.__init__(self,afi,peer,local)
23
24
		self.ttl = ttl
25
		self.afi = afi
26
		self.md5 = md5
27
		self.md5_base64 = md5_base64
28
		self.port = port
29
30
	def _setup (self):
31
		try:
32
			self.io = create(self.afi)
33
			MD5(self.io,self.peer,self.port,self.md5,self.md5_base64)
34
			if self.afi == AFI.ipv4:
35
				TTL(self.io, self.peer, self.ttl)
36
			elif self.afi == AFI.ipv6:
37
				TTLv6(self.io, self.peer, self.ttl)
38
			if self.local:
39
				bind(self.io,self.local,self.afi)
40
			asynchronous(self.io, self.peer)
41
			return True
42
		except NetworkError as exc:
43
			self.close()
44
			return False
45
46
	def _connect (self):
47
		try:
48
			connect(self.io,self.peer,self.port,self.afi,self.md5)
49
			return True
50
		except NetworkError as exc:
51
			return False
52
53
	def establish (self):
54
		last = time.time() - 2.0
55
		self._setup()
56
57
		while True:
58
			notify = (time.time() - last > 1.0)
59
			if notify:
60
				last = time.time()
61
62
			if notify:
63
				self.logger.debug('attempting connection to %s:%d' % (self.peer,self.port),self.session())
64
65
			if not self._connect():
66
				if notify:
67
					self.logger.debug('connection to %s:%d failed' % (self.peer,self.port),self.session())
68
				yield False
69
				continue
70
71
			connected = False
72
			for r,message in ready(self.io):
73
				if not r:
74
					yield False
75
					continue
76
				connected = True
77
78
			if connected:
79
				self.success()
80
				if not self.local:
81
					self.local = self.io.getsockname()[0]
82
				yield True
83
				return
84
85
			self._setup()
86
87
		# nagle(self.io,self.peer)
88
		# # Not working after connect() at least on FreeBSD TTL(self.io,self.peer,self.ttl)
89
		# yield True
90