~theiw/txstatsd/txstatsd-fix-831968

« back to all changes in this revision

Viewing changes to txstatsd/client.py

  • Committer: ian.wilkinson at canonical
  • Date: 2011-08-17 16:02:39 UTC
  • Revision ID: ian.wilkinson@canonical.com-20110817160239-fi0r8lfrau4571ly
Provide robust handling of network exceptions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
        @param disconnect_callback: The callback to invoke on disconnection.
36
36
        """
37
37
 
 
38
        # Twisted currently does not offer an asynchronous
 
39
        # getaddrinfo-like functionality
 
40
        # (http://twistedmatrix.com/trac/ticket/4362).
 
41
        # See UdpStatsDClient.
38
42
        self.host = host
39
43
        self.port = port
40
44
        self.connect_callback = connect_callback
56
60
        self.transport = None
57
61
 
58
62
    def write(self, data):
59
 
        """Send the metric to the StatsD server."""
 
63
        """Send the metric to the StatsD server.
 
64
                
 
65
        @param data: The data to be sent.
 
66
        @raise twisted.internet.error.MessageLength: If the size of data
 
67
            is too great.
 
68
        """
60
69
        if self.transport is not None:
61
 
            self.transport.write(data, (self.host, self.port))
 
70
            try:
 
71
                return self.transport.write(data, (self.host, self.port))
 
72
            except (OverflowError, TypeError, socket.error, socket.gaierror):
 
73
                return None
62
74
 
63
75
 
64
76
class UdpStatsDClient(object):
69
81
 
70
82
        @param host: The StatsD host.
71
83
        @param port: The StatsD port.
 
84
        @raise ValueError: If the C{host} and C{port} cannot be
 
85
            resolved (for the case where they are not C{None}).
72
86
        """
 
87
        if host is not None and port is not None:
 
88
            try:
 
89
                socket.getaddrinfo(host, port,
 
90
                                   socket.AF_INET, socket.SOCK_DGRAM)
 
91
            except (TypeError, socket.error, socket.gaierror):
 
92
                raise ValueError("The address cannot be resolved.")
 
93
 
73
94
        self.host = host
74
95
        self.port = port
 
96
        self.socket = None
75
97
 
76
98
    def connect(self):
77
99
        """Connect to the StatsD server."""
78
100
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
79
 
        self.addr = (self.host, self.port)
80
101
 
81
102
    def disconnect(self):
82
103
        """Disconnect from the StatsD server."""
86
107
 
87
108
    def write(self, data):
88
109
        """Send the metric to the StatsD server."""
89
 
        if self.addr is None or self.socket is None:
 
110
        if self.host is None or self.port is None or self.socket is None:
90
111
            return
91
 
        self.socket.sendto(data, self.addr)
 
112
        try:
 
113
            return self.socket.sendto(data, (self.host, self.port))
 
114
        except (socket.error, socket.herror, socket.gaierror):
 
115
            return None
92
116
 
93
117
 
94
118
class InternalClient(object):