# -*- coding: utf-8 -*-
import socket
import time

from beaver.transports.base_transport import BaseTransport


class TcpTransport(BaseTransport):

    def __init__(self, beaver_config, logger=None):
        super(TcpTransport, self).__init__(beaver_config, logger=logger)

        self._is_valid = False
        self._tcp_host = beaver_config.get('tcp_host')
        self._tcp_port = beaver_config.get('tcp_port')

        self._connect()

    def _connect(self):
        wait = -1
        while True:
            wait += 1
            time.sleep(wait)
            
            if wait == 20:
                return False

            if wait > 0:
                self._logger.info("Retrying connection, attempt {0}".format(wait + 1))

            try:
                self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP
                self._sock.connect((self._tcp_host, int(self._tcp_port)))
            except Exception:
                pass
            else:
                self._logger.info("Connected")
                self._is_valid = True
                return True

    def reconnect(self):
        self._connect()

    def invalidate(self):
        """Invalidates the current transport"""
        super(TcpTransport, self).invalidate()
        self._sock.close()

    def callback(self, filename, lines, **kwargs):
        timestamp = self.get_timestamp(**kwargs)
        if kwargs.get('timestamp', False):
            del kwargs['timestamp']

        for line in lines:
            self._sock.send(self.format(filename, line, timestamp, **kwargs) + "\n")

@@ -31,16 +31,29 @@
  socket%0A
+import errno%0A
 import t
@@ -116,16 +116,75 @@
 ansport%0A
+from beaver.transports.exception import TransportException%0A
 %0A%0Aclass 
@@ -1541,16 +1541,33 @@
 tamp'%5D%0A%0A
+        try:%0A    
         
@@ -1585,16 +1585,20 @@
  lines:%0A
+    
         
@@ -1674,8 +1674,471 @@
 + %22%5Cn%22)%0A
+        except socket.error, e:%0A            self.invalidate()%0A%0A            if isinstance(e.args, tuple):%0A                if e%5B0%5D == errno.EPIPE:%0A                    raise TransportException('Connection appears to have been lost')%0A            %0A            raise TransportException('Socket Error: %25s', e.args)%0A        except Exception:%0A            self.invalidate()%0A%0A            raise TransportException('Unspecified exception encountered')  # TRAP ALL THE THINGS!%0A

Handle publication failures in the TCP transport correctly