Exemple #1
0
class Seller(ResourceAgent, Trader):

    def __init__(self, node, rationale, **kw):
        ResourceAgent.__init__(self, node)
        Trader.__init__(self, rationale, **kw)
        self.trace = Tracer(node)
        self.trace = self.trace.add('%-12s' % self)
        self.listen_process = None
        self.quote_timeouts = dict()

    def start(self):
        self.listen_process = ListenProcess(self)
        activate(self.listen_process, self.listen_process.listen())
  

    def set_quote_timeout(self, quote, trace):
        trace and trace("setting rationale timeout %s" % (id, ))
        p = RationaleTimeout()
        p.start(p.timeout(self, quote.id, quote, self.quote_timeout, trace))
        self.quote_timeouts[quote.id] = p

    def cancel_quote_timeout(self, id, trace):
        if id in self.quote_timeouts:
            trace and trace("cancelling rationale timeout %s" % (id, ))
            process = self.quote_timeouts[id]
            cancel_process(process)
            del self.quote_timeouts[id]
        elif id in self.timedout:
            trace and trace("rationale timeout already fired %s" % (id, ))
        elif trace:
            trace("WARNING: unknown quote timeout cancelled %s" % (id, ))

    def process_quote_timeout(self, id, quote, trace):
        if id in self.quote_timeouts:
            trace and trace("observing failed quote %s" % (id, ))
            self.rationale.observe(quote, False)
            self.timedout.add(id)
            del self.quote_timeouts[id]
        elif id in self.timedout:
            trace("WARNING: quote timeout already timed out %s" % (id, ))
        else:
            trace("WARNING: unknown quote timeout firing %s" % (id, ))


    # utility function
    def create_quote(self):
        self.price = self.rationale.quote()
        return Ask(None, self, self.resource.free, self.price)

    def create_accept(self, quote):
        return Ask(quote.buyer, self, quote.job, quote.price)

    def viable_quote(self, q):
        return (self.active and
                self.bid and
                q.price >= self.price and
                q.size <= self.node.resource.free)
Exemple #2
0
class MdsResourceAgent(ResourceAgent):
    def __init__(self, node, update_time):
        ResourceAgent.__init__(self, node)
        self.update_time = update_time
        self.update_process = None
        self.listen_process = None
        self.trace = Tracer(self.node).add("ragent%-6s" % node.id)

    def accept(self, value):
        if self.listen_process:
            self.listen_process.signal("accept", value)
        else:
            self.trace("WARNING: no listen process for accept")

    @property
    def broker(self):
        return self.node.broker

    def start(self):
        self.update_process = ResourceUpdateProcess(self)
        self.update_process.start(self.update_process.update())
        self.listen_process = ResourceListenProcess(self)
        self.listen_process.start(self.listen_process.listen())

    # accept received
    def accept_received(self, alloc):
        job = alloc.jagent.job
        trace = self.trace.add("j%-5s" % job.id)
        if self.resource.can_allocate(job):
            trace and trace("accept from %s, starting" % alloc.jagent)
            self.confirm_and_start_job(job, alloc.jagent, alloc)
        else:
            trace and trace("accept from %s, busy, rejecting" % alloc.jagent)
            self.send_reject(alloc.jagent, alloc)


    def __str__(self):
        return "ragent%d" % self.node.id
Exemple #3
0
class Broker(object):

    def __init__(self, region, node, registry, sync_time, others):
        self.region = region
        self.node = node
        self.registry = registry
        self.sync_time = sync_time
        self.others = others
        self.listen_process = None
        self.trace = Tracer(node).add("bkr%-9s" % region)

    def __str__(self):
        return "broker %d" % self.region

    def start(self):
        self.listen_process = BrokerListenProcess(self)
        self.listen_process.start(self.listen_process.listen())
        self.update_process = BrokerUpdateProcess(self)
        self.update_process.start(self.update_process.update())

    def allocate(self, allocation):
        trace = self.trace.add("j%-5s" % allocation.jagent.job.id)
        
        trace and trace("alloc request from %s" % allocation.jagent)
        states = self.registry.get_resources(allocation)
        # return the best system wide fit
        states.sort(key=lambda x: x.free)

        if states:
            state = states[0]
            alloc = Allocation(allocation.jagent, state.agent)
            msg = AllocationResponse(alloc)
            msg.send_msg(self.node, alloc.jagent.node)
            trace and trace("returning alloc %s" % alloc)
            state.free -= allocation.job.size
        else:
            trace and trace("no valid allocations")


    def update(self, state):
        self.trace and self.trace("updating state for %s" % state.agent)
        self.registry.update_state(state)

    @property
    def other_brokers(self):
        for other in self.others.itervalues():
            if other is not self:
                yield other

    def send_sync(self):
        states = SyncDict(self)
        for agent, state in self.registry.states.iteritems():
            states[agent] = ResourceState(agent, state.free)

        for other in self.other_brokers:
            self.trace and self.trace("sending sync to %s" % other)
            msg = SyncMessage(states)
            msg.send_msg(self.node, other.node)


    def sync(self, states):
        self.trace and self.trace("syncing states from %s" % states.broker)
        #print "xxx"
        #print "----"
        #for state in self.registry.states.itervalues():
        #    print state.agent, state.free
        #print "----"
        for state in states.itervalues():
            #print state.agent, state.free
            self.registry.update_state(state)
Exemple #4
0
class Buyer(JobAgent, Trader):
    def __init__(self, job, rationale, **kw):
        JobAgent.__init__(self, job)
        Trader.__init__(self, rationale, **kw)
        self.migrations = 0
        self.listen_process = None

        self.accepted = set()

    def start(self):
        self.start_time = now()
        self.node.job_agents.add(self)
        self.listen_process = ListenProcess(self)
        activate(self.listen_process, self.listen_process.listen())
    
    def start_on_node(self, node):
        self.node = node
        self.regions.add(self.node.region)
        self.trace = Tracer(node)
        self.trace = self.trace.add('%-12s' % self)
        self.trace = self.trace.add('j%-5d' % self.job.id)
        self.trace and self.trace("starting on %s" % node)
        self.start()


    # buyer mobility utilities
    def remove_from_node(self):
        self.trace and self.trace("removing from %s" % self.node)
        self.node.job_agents.remove(self)
        self.node.old_job_agents.add(self)

    def migrate(self):
        self.trace and self.trace("migrating")
        
        current = self.node
        self.remove_from_node()
        
        r = self.node.graph.regions
        max = r[0] * r[1]

        if len(self.regions) == max:
            self.regions = set()
            others = self.node.graph.nodes()
        else:
            # choose another node in a different region
            others = [n for n in self.node.graph.nodes_iter() 
                      if n.region not in self.regions]

        other = random.choice(others)
        while other == current:
            other = random.choice(others)
        
        #cancel any events (there shouldn't be, but just in case)
        self.cancel_all()

        self.trace and self.trace("moving to %s" % other)
        self.start_on_node(other)
  
    def finish_trading(self):
        self.remove_from_node()
        self.active = False
    
    # utility functions
    def create_quote(self):
        self.price = self.rationale.quote()
        return Bid(self, None, self.job, self.price)

    def create_accept(self, quote):
        return Bid(self, quote.seller, self.job, quote.price)

    def viable_quote(self, q):
        return (self.active and 
                q.ask and 
                q.price <= self.price and 
                q.size >= self.job.size)
Exemple #5
0
class MdsJobAgent(JobAgent):
    def __init__(self, job, allocate_timeout, accept_timeout, max_attempts):
        JobAgent.__init__(self, job)
        self.allocate_timeout = allocate_timeout
        self.accept_timeout = accept_timeout
        self.allocation = Allocation(self, None)
        self.attempts = 0
        self.max_attempts = max_attempts
        

    @property
    def broker(self):
        return self.node.broker

    def send_allocation_request(self):
        if self.attempts < self.max_attempts:
            self.allocation = Allocation(self, None)
            self.attempts += 1
            self.trace and self.trace("sending allocation (%s)", self.attempt)
            self.allocate_process = AllocateProcess(self)
            self.allocate_process.start(self.allocate_process.allocate())
            msg = AllocationRequest(self.allocation)
            msg.send_msg(self.node, self.broker.node)
        else:
            self.trace and self.trace("allocation attemps execeeded")
            self.record_failure(self.allocation)
            self.cancel_all()

    def start(self):
        self.send_allocation_request()

    def start_on(self, node):
        self.node = node
        self.node.job_agents.add(self)
        self.trace = Tracer(self.node).add("jagent%-6s" % self.job.id)
        self.trace = self.trace.add("j%-5s" % self.job.id)
        self.start()

    def response(self, alloc):
        self.trace and self.trace("got allocation: %s" % alloc)
        if (alloc.ragent):
            self.allocation = alloc
            self.trace and self.trace("sending accept to %s" % alloc.ragent)
            self.start_accept_process(alloc.ragent, alloc, self.accept_timeout)
        else:
            self.trace and self.trace("broker gave null alloc")
            self.send_allocation_request()
            

    def allocate_timedout(self):
        self.trace and self.trace("allocation request timedout")
        self.send_allocation_request()


    #internal AcceptProcess interface
    def confirm_received(self, confirm):
        if confirm == self.allocation:
            self.trace and self.trace("accept confirmed")
            self.record_success(confirm)
            self.cancel_all()
            self.accept_process = None

        elif confirm in self.timedout: # old confirms
            self.trace and self.trace("got confirm from timed out quote")
        else: # unknown confirm
            self.trace("WARNING: got random confirm: %s" % confirm)

    def reject_received(self, reject):
        if reject == self.allocation: # allocation rejected
            self.trace and self.trace("accept rejected")
            self.send_allocation_request()

        elif reject in self.timedout:
            self.trace and self.trace("accept rejected, but had already timed out")
        else:
            self.trace("WARNING: got reject for unknown quote: %s" % reject)
   
    def accept_timedout(self, accept):
        self.trace and self.trace(" accept timed out, sending cancel")
        cancel = Cancel(self, accept.ragent, accept)
        cancel.send_msg(self.node, accept.ragent.node)
        self.send_allocation_request()


    def record_failure(self, alloc):
        record.record_failure(self, alloc)

    def record_success(self, alloc):
        record.record_success(self, alloc)


    def __str__(self):
        return "jagent%d" % self.job.id