示例#1
0
    def remote_tellOutput(self, ip, output):
        """
        ip:str | output:serializable -> None
        
        Marks completion in database
        Verifies job that client is returning
        """
        # Get relevant assignment
        assignment = fi.job.model.Assignment.lookup(ip)

        # Mark it complete in database
        fi.job.model.Assignment.complete(ip, output)
        
        fi.logmsg(
            self.__class__,
            "Completed %d-%d-%d for %s" % (
                assignment.job.id,
                assignment.instance.id,
                assignment.id,
                ip,
            )
        )
      
        # Verify returned result
        fi.job.verifier.Verifier.verify(assignment)
示例#2
0
    def schedule(cls, credits):
        """
        credits:[(str, int)] -> None
        
        """
        fi.logmsg(cls, "Scheduling")
        
        max_credit = max(
            credits,
            key=lambda x: x[1]
        )[1]
        
        # This right here is essentially the scheduling, converting the credit to proportional numbers
        logs = [
            (ip, math.log1p(credit + 1))
            for (ip, credit) in credits
        ]
            
        total_log = reduce(
            lambda x, y: x + y,
            (n
             for (_, n) in logs)
        )

        allocations = (
            (ip, (log / total_log) * fi.throttle.AVAILABLE_BANDWIDTH)
            for (ip, log) in logs
        )
        
        return allocations
示例#3
0
 def onPathloadReceive(cls, data):
     """
     data:str -> None
     
     Receives bandwidth data in form "float float" and sets max bandwidth
     Calls receive funciton again
     """
     try:
         lines = data.split('\n')
         high = 0
         low = 0
         
         for line in lines:
             if 'Available' in line:
                 words = line.split()
                 low = float(words[4])
                 high = float(words[6])
         
         if high and low:
             available = (high + low) / 8 / 2 * 1000
             fi.logmsg(cls, "Setting new available bandwidth to ", available, "kbps")
             # Convert from Mbps to kBps and set to available bandwidth
             
             fi.throttle.AVAILABLE_BANDWIDTH = available
     except ValueError, e:
         fi.logmsg(cls, "Unsuccessful parsing for available bandwidth")
示例#4
0
    def onPathloadReceive(cls, data):
        """
        data:str -> None
        
        Receives bandwidth data in form "float float" and sets max bandwidth
        Calls receive funciton again
        """
        try:
            lines = data.split('\n')
            high = 0
            low = 0

            for line in lines:
                if 'Available' in line:
                    words = line.split()
                    low = float(words[4])
                    high = float(words[6])

            if high and low:
                available = (high + low) / 8 / 2 * 1000
                fi.logmsg(cls, "Setting new available bandwidth to ",
                          available, "kbps")
                # Convert from Mbps to kBps and set to available bandwidth

                fi.throttle.AVAILABLE_BANDWIDTH = available
        except ValueError, e:
            fi.logmsg(cls, "Unsuccessful parsing for available bandwidth")
示例#5
0
    def toldBandwidth(self, bandwidth):
        fi.logmsg(self.__class__, "Told %dkbps" % bandwidth)

        ThrottleApplication.throttle(
            ((fi.throttle.VPN_SERVER_IP, bandwidth),)
        )
                
        self.gotRoot(self.root)
示例#6
0
 def askBandwidth(self):
     fi.logmsg(self.__class__, "Ask bandwidth")
     bandwidth_d = self.root.callRemote(
         "tellBandwidth",
         self.ip
     )
     
     bandwidth_d.addCallbacks(
         self.toldBandwidth,
         self.gotNothing,
     )
示例#7
0
    def toldJob(self, job):
        """
        job:(str, str, serializable) -> None
        
        Called after job as been transferred
        """

        # Unpack
        try:
            name, module_input, job_input = job
        except ValueError, e:
            fi.logmsg(self.__class__, "Invalid job")
            self.getRoot()
            return
示例#8
0
 def toldJob(self, job):
     """
     job:(str, str, serializable) -> None
     
     Called after job as been transferred
     """
     
     # Unpack
     try:
         name, module_input, job_input = job
     except ValueError, e:
         fi.logmsg(self.__class__, "Invalid job")
         self.getRoot()
         return
示例#9
0
    def throttle(cls, allocations):
        """
        allocations:[(str, int)] -> shell:fi.shell.Shell
        
        """

        fi.logmsg(cls, "Making allocations")
        
        shell = fi.throttle.shell.Shell()
        interface = fi.throttle.VPN_INTERFACE
        
        toRun = (
            # Drop current rules
            "/sbin/tc qdisc del dev %s root" % interface,
            "/sbin/iptables -t mangle -F",

            # Create queueing discipline on device root
            "/sbin/tc qdisc add dev %s root handle 1:0 htb" % interface,
            )

        # Run above commands
        for command in toRun:
            shell.add(command)

        # Create node, filter, and /sbin/iptables mark rule for each client
        for i, (ip, allocation) in enumerate(allocations):
            bandwidth = float(allocation) * fi.throttle.BANDWIDTH_HEURISTIC
            # Create classes off of root qdisc
            shell.add("/sbin/tc class add dev %s parent 1: classid 1:%d htb rate %sbps prio %d" % (
                interface, i + 1, bandwidth, i + 1
                )
            )

            # Mark traffic 
            shell.add("/sbin/iptables -t mangle -A POSTROUTING -d %s -j MARK --set-mark %d" % (
                ip, i + 1
                )
            )

            # Filter traffic
            shell.add("/sbin/tc filter add dev %s parent 1:0 protocol ip prio %d handle %d fw flowid 1:%d" % (
                interface, i + 1, i + 1, i + 1
                )
            )
            
        shell.execute()
示例#10
0
class JobClientController(fi.controller.ClientController):
    def gotRoot(self, root):
        self.root = root
        self.askJob()

    def askJob(self, *args):
        # Ask for next job
        fi.logmsg(self.__class__, "Receiving Job")
        job_d = self.root.callRemote("tellJob", self.ip)
        job_d.addCallbacks(self.toldJob, self.gotNothing)

    def toldJob(self, job):
        """
        job:(str, str, serializable) -> None
        
        Called after job as been transferred
        """

        # Unpack
        try:
            name, module_input, job_input = job
        except ValueError, e:
            fi.logmsg(self.__class__, "Invalid job")
            self.getRoot()
            return

        fi.logmsg(self.__class__, "Running %s on %s" % (name, job_input))

        # Load module into memory from code
        module = self.stringToModule(module_input, name)

        # Run job
        output = module.__getattribute__(name).getOutput(*job_input)

        fi.logmsg(self.__class__, "Returning job output")
        complete = self.root.callRemote(
            "tellOutput",
            self.ip,
            output,
        )

        def askAnother():
            complete.addCallbacks(self.askJob, self.gotNothing)

        fi.callLater(askAnother)
示例#11
0
    def remote_tellJob(self, ip):
        """
        ip:str -> str | str | _
        
        Gets the name, module code, and input list for the next job
        """
        assignment = fi.job.model.Assignment.nextJob(ip)
        fi.job.model.Assignment.record(ip, assignment)

        fi.logmsg(
            self.__class__, "Assigning %d-%d-%d to %s" % (
                assignment.job.id,
                assignment.instance.id,
                assignment.id,
                ip,
            ))

        return assignment.job.name, assignment.job.module, assignment.instance.input
示例#12
0
    def throttle(cls, allocations):
        """
        allocations:[(str, int)] -> shell:fi.shell.Shell
        
        """

        fi.logmsg(cls, "Making allocations")

        shell = fi.throttle.shell.Shell()
        interface = fi.throttle.VPN_INTERFACE

        toRun = (
            # Drop current rules
            "/sbin/tc qdisc del dev %s root" % interface,
            "/sbin/iptables -t mangle -F",

            # Create queueing discipline on device root
            "/sbin/tc qdisc add dev %s root handle 1:0 htb" % interface,
        )

        # Run above commands
        for command in toRun:
            shell.add(command)

        # Create node, filter, and /sbin/iptables mark rule for each client
        for i, (ip, allocation) in enumerate(allocations):
            bandwidth = float(allocation) * fi.throttle.BANDWIDTH_HEURISTIC
            # Create classes off of root qdisc
            shell.add(
                "/sbin/tc class add dev %s parent 1: classid 1:%d htb rate %sbps prio %d"
                % (interface, i + 1, bandwidth, i + 1))

            # Mark traffic
            shell.add(
                "/sbin/iptables -t mangle -A POSTROUTING -d %s -j MARK --set-mark %d"
                % (ip, i + 1))

            # Filter traffic
            shell.add(
                "/sbin/tc filter add dev %s parent 1:0 protocol ip prio %d handle %d fw flowid 1:%d"
                % (interface, i + 1, i + 1, i + 1))

        shell.execute()
示例#13
0
    def schedule(cls, credits):
        """
        credits:[(str, int)] -> None
        
        """
        fi.logmsg(cls, "Scheduling")

        max_credit = max(credits, key=lambda x: x[1])[1]

        # This right here is essentially the scheduling, converting the credit to proportional numbers
        logs = [(ip, math.log1p(credit + 1)) for (ip, credit) in credits]

        total_log = reduce(lambda x, y: x + y, (n for (_, n) in logs))

        allocations = ((ip,
                        (log / total_log) * fi.throttle.AVAILABLE_BANDWIDTH)
                       for (ip, log) in logs)

        return allocations
示例#14
0
 def remote_tellJob(self, ip):
     """
     ip:str -> str | str | _
     
     Gets the name, module code, and input list for the next job
     """
     assignment = fi.job.model.Assignment.nextJob(ip)
     fi.job.model.Assignment.record(ip, assignment)
                     
     fi.logmsg(
         self.__class__,
         "Assigning %d-%d-%d to %s" % (
             assignment.job.id,
             assignment.instance.id,
             assignment.id,
             ip,
         )
     )
     
     return assignment.job.name, assignment.job.module, assignment.instance.input
示例#15
0
    def remote_tellOutput(self, ip, output):
        """
        ip:str | output:serializable -> None
        
        Marks completion in database
        Verifies job that client is returning
        """
        # Get relevant assignment
        assignment = fi.job.model.Assignment.lookup(ip)

        # Mark it complete in database
        fi.job.model.Assignment.complete(ip, output)

        fi.logmsg(
            self.__class__, "Completed %d-%d-%d for %s" % (
                assignment.job.id,
                assignment.instance.id,
                assignment.id,
                ip,
            ))

        # Verify returned result
        fi.job.verifier.Verifier.verify(assignment)
示例#16
0
 def gotNothing(self, reason):
     """For callRemote failures"""
     fi.logmsg(self.__class__, "Remote call failed: " + str(reason))
示例#17
0
 def getRoot(self, *args):
     """Can be called to re-get the server root object"""
     fi.logmsg(self.__class__, "Receiving remote root")
     root_d = self.getRootObject()
     root_d.addCallbacks(self.gotRoot, self.gotNothing)
示例#18
0
    def clientConnectionFailed(self, connector, reason):
        fi.logmsg(self.__class__, "Connection lost")

        fi.callLater(connector.connect)

        fi.logmsg(self.__class__, "Reconnecting...")
示例#19
0
 def clientConnectionMade(self, connector):
     pb.PBClientFactory.clientConnectionMade(self, connector)
     
     fi.logmsg(self.__class__, "Connected to server")
     self.ip = connector.transport.getHost().host
     self.getRoot()
示例#20
0
 def askJob(self, *args):
     # Ask for next job
     fi.logmsg(self.__class__, "Receiving Job")
     job_d = self.root.callRemote("tellJob", self.ip)
     job_d.addCallbacks(self.toldJob, self.gotNothing)
示例#21
0
 def askJob(self, *args):
     # Ask for next job
     fi.logmsg(self.__class__, "Receiving Job")
     job_d = self.root.callRemote("tellJob", self.ip)
     job_d.addCallbacks(self.toldJob, self.gotNothing)
示例#22
0
 def gotNothing(self, reason):
     """For callRemote failures"""
     fi.logmsg(self.__class__, "Remote call failed: " + str(reason))
示例#23
0
 def getRoot(self, *args):
     """Can be called to re-get the server root object"""
     fi.logmsg(self.__class__, "Receiving remote root")
     root_d = self.getRootObject()
     root_d.addCallbacks(self.gotRoot, self.gotNothing)
示例#24
0
    def clientConnectionFailed(self, connector, reason):
        fi.logmsg(self.__class__, "Connection lost")

        fi.callLater(connector.connect)

        fi.logmsg(self.__class__, "Reconnecting...")
示例#25
0
    def clientConnectionMade(self, connector):
        pb.PBClientFactory.clientConnectionMade(self, connector)

        fi.logmsg(self.__class__, "Connected to server")
        self.ip = connector.transport.getHost().host
        self.getRoot()
示例#26
0
 def remote_tellBandwidth(self, ip):
     bandwidth = fi.throttle.model.Client.get_by(ip=ip).bandwidth
     fi.logmsg(self.__class__, "Tell %s %dkbps" % (ip, bandwidth))
     return bandwidth