<commit_before>#!/usr/bin/env python

# parts of this may look strangely familiar to anyone who wrote ThreadedComponent :)
#
#
# In order for a seperate thread to communicate information into a kamaelia system,
# we must have Queue objects that carry all communications, meaning something like 
# a threadedcomponent turned inside out.
#
#
#
#
#            +------------------------------------------+
#            |            the outside world             |
#            |                                          |
#            |              +-----------+               |
#            |              | scheduled |               |
#  (STDIN) INBOX -------> inbox       outbox -------> OUTBOX (STDOUT)
#            |  inqueue     | component |  outqueue     |
#            |              +-----------+               |
#            +------------------------------------------+
#
#
#
#



from Axon.Component import component
from Axon.Scheduler import scheduler
from Axon.AxonExceptions import noSpaceInBox
import Queue, copy, threading
queuelengths = 1000



class schedulerThread(threading.Thread):
    def __init__(self,slowmo=0):
        self.slowmo = slowmo
        threading.Thread.__init__(self)
        self.setDaemon(True) # Die when the interactive shell dies
    def run(self):
       scheduler.run.runThreads(slowmo = self.slowmo)


class Componentwrapper(component):
    def __init__(self, childcomponent):
        self.queuelengths = queuelengths
        self.child = childcomponent
        self.inqueues = dict()
        self.outqueues = dict()
        self.addChildren(childcomponent)

        # create a queue for every inbox or outbox on the target component we need to wrap around.
        # It would be nice if we could just read/write to the target component's boxes directly.
        # in this case, we need 2 sets of queues. In one, the source is our inqueues and the sink 
        # is the inboxes of the target component.
        # In othe other, the source is the outboxes of the target component and the sink is our outqueues.


        for box in self.component.inboxes.iterkeys():
            self.inqueues[box] = Queue.Queue(self.queuelengths)
        for box in self.component.outboxes.iterkeys():
            self.outqueues[box] = Queue.Queue(self.queuelengths)

        # insert code here to hook them up correctly.

        super(Componentwrapper, self).__init__()



    def main(self):
        while True:
            stuffWaiting = False
            for box, queue in self.inqueues.iteritems():
                # to aid a lack of confusion, this is where information would traverse from stdin to a component's inbox.
                while not queue.empty():
                    if not self.child.inboxes[box].isFull():
                        msg = queue.get()
                        try:
                            self.child.send(msg, box) # WRONG
                        except noSpaceInBox, e:
                            raise "Box delivery failed despite box (earlier) reporting being not full. Is more than one thread directly accessing boxes?"
                    else:
                        stuffWaiting = True
                        break

            for box, queue in self.outqueues.iteritems():
                # to aid a lack of confusion, this is where information would traverse from a component's outbox to stdout.
                while self.component.dataReady(box):
                    if not queue.full():
                        msg = self.child.recv(box) # WRONG
                        self.inqueues[box].put(msg)
                    else:
                        stuffWaiting = True
                        break
            if not stuffWaiting: self.pause() # go to sleep unless we know we have un-processed data.
            yield 1

class Likefile(object):
    def __init__(self, componenttowrap):
        self.component = Componentwrapper(componenttowrap)
        self.component.activate()
    def get(self, boxname):
        return self.component.outqueues[boxname].get()
    def put(self, msg, boxname):
        self.component.inqueues[boxname].put(msg)

background = schedulerThread(slowmo=0.01)

background.start()

from helloworld import Reverser
import time

p = Likefile(Reverser())

while True:
    p.put("hello, world", "inbox")
    time.sleep(1)
    print p.get("outbox")<commit_msg>working alpha of likefile. <commit_after>#!/usr/bin/env python

# parts of this may look strangely familiar to anyone who wrote ThreadedComponent :)
#
#
# In order for a seperate thread to communicate information into a kamaelia system,
# we must have Queue objects that carry all communications, meaning something like 
# a threadedcomponent or a UnixProcess turned inside out.
#


from Axon.AdaptiveCommsComponent import AdaptiveCommsComponent
from Axon.Scheduler import scheduler
from Axon.AxonExceptions import noSpaceInBox
import Queue, copy, threading
queuelengths = 1000



class schedulerThread(threading.Thread):
    def __init__(self,slowmo=0):
        self.slowmo = slowmo
        threading.Thread.__init__(self)
        self.setDaemon(True) # Die when the caller dies
    def run(self):
       scheduler.run.runThreads(slowmo = self.slowmo)


class Componentwrapper(AdaptiveCommsComponent):
    def __init__(self, childcomponent):
        super(Componentwrapper, self).__init__()
        self.queuelengths = queuelengths
        self.child = childcomponent
        self.inqueues = dict() # queue for data traversing from stdin to a component's inbox
        self.outqueues = dict()# queue for data traversing from stdout to a component's outbox
        self.addChildren(self.child)
        self.child.activate()

        # todo: insert a control linking here.

        # Inspect our child, and whatever inboxes it has, give ourselves an outbox of the same name.
        # This is an ugly hack. It would better to have a custom mapping so that the componentwrapper's "outbox" 
        # sends to the child's "inbox" like every other kamaelia component.

        for box in self.child.inboxes.iterkeys():
            self.inqueues[box] = Queue.Queue(self.queuelengths)
            if box != self.addOutbox(box):
                raise "box name taken when encapsulating! This really ought not to happen!"
            self.link((self, box), (self.child, box))
            # this leads to the confusing situation where we have an outbox called "inbox"
            # having all the box names the same between parent and child makes this programmatically easier.

        for box in self.child.outboxes.iterkeys():
            self.outqueues[box] = Queue.Queue(self.queuelengths)
            if box != self.addInbox(box):
                raise "box name taken when encapsulating! This really ought not to happen!"
            self.link((self.child, box), (self, box))


    def main(self):
        while True:
            for box, queue in self.inqueues.iteritems():
                # to aid a lack of confusion, this is where information would traverse from stdin to a component's inbox.
                while not queue.empty():
                    if not self.outboxes[box].isFull():
                        msg = queue.get()
                        try:
                            self.send(msg, box)
                        except noSpaceInBox, e:
                            raise "Box delivery failed despite box (earlier) reporting being not full. Is more than one thread directly accessing boxes?"
                    else: break


            for box, queue in self.outqueues.iteritems():
                # to aid a lack of confusion, this is where information would traverse from a component's outbox to stdout.
                while self.dataReady(box):
                    if not queue.full():
                        msg = self.recv(box)
                        queue.put(msg)
                    else: break # permit a horrible backlog to build up inside our boxes. What could go wrong?
            yield 1

class Likefile(object):
    def __init__(self, componenttowrap):
        self.component = Componentwrapper(componenttowrap)
        self.component.activate()
        self.alive = True

    def get(self, boxname):
        if self.alive: return self.component.outqueues[boxname].get_nowait()
        else: raise "shutdown was previously called!"

    def put(self, msg, boxname):
        if self.alive: self.component.inqueues[boxname].put_nowait(msg)
        else: raise "shutdown was previously called!"

    def shutdown(self):
        # put shutdown code here
        pass



if __name__ == "__main__":
    background = schedulerThread(slowmo=0.01)
    background.start()
    from helloworld import Reverser
    import time
    
    p = Likefile( Reverser() )
    while True:
        p.put("hello, world", "inbox")
        time.sleep(0.5) # longer than axon's slowdown period
        reversed = p.get("outbox")
        print "hello world, reversed, is:" , reversed
{'fraction_non_alphanumeric': 0.09019870506809556, 'fraction_numerical': 0.002455905336012503, 'mean_word_length': 1.9734483903086624, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2062700', 'n_tokens_mistral': 2424, 'n_tokens_neox': 2277, 'n_words': 799}