class Client:
    def __init__(self, host='localhost', port='8888'):
        self._url = 'ws://{}:{}/exchange'.format(host, port)
        self.conn = None
        self.opened = Subject()
        self.messages = Subject()

    def connect(self):
        def on_connect(conn):
            self.conn = conn
            self.opened.on_next(conn)
            self.opened.on_completed()
            self.opened.dispose()

        def on_message_callback(message):
            self.messages.on_next(message)

        future = websocket_connect(
            self._url,
            on_message_callback=on_message_callback
        )
        Observable.from_future(future).subscribe(on_connect)

    def write_message(self, message):
        self.conn.write_message(message)
Exemplo n.º 2
0
class TtyScanner(object):
    def __init__(self) -> None:

        self.__added_devices = Subject()
        self.__removed_devices = Subject()
        self.__stop_flag = threading.Event()

    def scan(self) -> None:
        threading.Thread(target=self.__work).start()

    def __work(self) -> None:

        context = pyudev.Context()
        monitor = pyudev.Monitor.from_netlink(context)
        monitor.filter_by(subsystem="tty")
        monitor.enable_receiving()

        for device in context.list_devices(subsystem="tty", ID_BUS="usb"):
            self.__added_devices.on_next(device)

        while not self.__stop_flag.is_set():

            device = monitor.poll(timeout=1)

            if device is None:
                continue

            if not re.search("ttyUSB\\d+", device.sys_name):
                continue

            if device.action == "add":
                self.__added_devices.on_next(device)

            elif device.action == "remove":
                self.__removed_devices.on_next(device)

    def stop(self) -> None:

        self.__stop_flag.set()
        self.__added_devices.dispose()
        self.__removed_devices.dispose()

    @property
    def added_devices(self) -> Observable[Device]:
        return self.__added_devices

    @property
    def removed_devices(self) -> Observable[Device]:
        return self.__removed_devices
Exemplo n.º 3
0
class Device(Generic[T], Closeable, ABC):
    def __init__(self):
        super().__init__()

        self.__latest_values: Dict[ValueType, DeviceValue] = dict()
        self.__value_subject = Subject()

    def close(self, reason: str = None) -> None:
        super().close(reason)

        self.__value_subject.dispose()

    def get_values(self) -> Observable:

        return rx.concat(rx.from_list(self.__latest_values.values()),
                         self.__value_subject)

    @abstractmethod
    def get_type(self) -> DeviceType:
        pass

    @abstractmethod
    def get_product(self) -> str:
        pass

    @abstractmethod
    def get_serial_number(self) -> str:
        pass

    def _publish_value(self, value: DeviceValue) -> None:

        self.__latest_values[value.type] = value
        self.__value_subject.on_next(value)

    def __hash__(self) -> int:
        return hash(self.get_serial_number())

    def __eq__(self, other: Device) -> bool:
        return self.get_serial_number() == other.get_serial_number()

    def __str__(self):
        return f"{self.get_product()} ({self.get_serial_number()})"
Exemplo n.º 4
0
class DockerExperiment():
    def __init__(self, env):
        self.counter = 0
        self.state = "work"
        self.env = env
        self.problem_id = env["problem"]["problem_id"]
        self.consumed_messages = Subject()
        self.messages = Subject()
        self.population_objects_topic = "population-objects"
        self.consumed_messages\
            .filter(lambda x: x["problem"]["problem_id"] == self.problem_id) \
            .take(env["problem"]["max_iterations"])\
            .buffer_with_count(3)\
            .subscribe( on_next=lambda x : self.population_mixer(x),on_completed = self.finish)

        self.consumed_messages.subscribe(
            lambda message: self.one_more(message),
            on_completed=lambda: print("MESSAGES COMPLETED"))
        self.messages.publish()

        self.messages.subscribe(
            lambda populations: self.produce(populations),
            on_completed=lambda: print("MESSAGES COMPLETED"))

    def one_more(self, message):
        #print(message)
        print('CONSUMED:{}, Max {}'.format(
            self.counter, self.env["problem"]["max_iterations"]))
        self.counter += 1
        if 'best_score' in message:
            error = abs(message['best_score'] - message["fopt"])
            print('Best:{}, Fopt {}, Error {}'.format(message['best_score'],
                                                      message["fopt"], error))

            if 1e-8 >= error:
                self.finish()

    def finish(self):

        print("Consume Finished")
        self.state = "stop"
        self.messages.on_completed()
        self.messages.dispose()
        #sys.exit(0)

    def population_mixer(self, populations):
        if len(populations) == 3:
            print("MIXER:", len(populations))
            #populations = [json.loads(message.data) for message in populations]contr
            populations[0]['population'] = cxBestFromEach(
                populations[0]['population'], populations[1]['population'])
            populations[1]['population'] = cxBestFromEach(
                populations[1]['population'], populations[2]['population'])
            populations[2]['population'] = cxBestFromEach(
                populations[2]['population'], populations[0]['population'])

            # I can´t fo map(...on_next, populations )
            self.messages.on_next(populations[0])
            self.messages.on_next(populations[1])
            self.messages.on_next(populations[2])

    def read_from_queue(self):
        print("worker start")
        while self.state == 'work':
            print('working')
            data = None
            message = r.blpop(TOPIC_CONSUME, 2)
            if not message:
                print("NO DATA, WAITING...")
                time.sleep(2)
            else:
                data = message[1]

                pop_dict = json.loads(data)

                #print("message:data:", pop_dict)
                #print("message:type:", type(pop_dict))
                #if 'best_score' in pop_dict:
                #    error = abs(pop_dict['best_score']-pop_dict["fopt"])
                #    print ('Best:{}, Fopt {}, Error {}'.format( pop_dict['best_score'], pop_dict["fopt"], error  ))
                #if 1e-8 >= error:
                #    self.finish()

                print("message read from queue")
                self.log_to_redis_coco(pop_dict)
                self.consumed_messages.on_next(pop_dict)

        return self.problem_id

    def produce(self, population):
        print("pop sent:", "population")
        json_data = json.dumps(population)
        # Data must be a bytestring
        message = json_data.encode('utf-8')
        ack = r.lpush(TOPIC_PRODUCE, message)
        print("Produce:", ack)

    def log_to_redis_coco(self, population):
        log_name = "log:swarm"
        r.lpush(log_name, json.dumps(self.get_benchmark_data(population)))

    def get_benchmark_data(self, population):
        #print("\n\npopulation\n\n", population)
        return {
            "time_stamp":
            datetime.timestamp(datetime.now()),
            "evals":
            population["iterations"],
            "instance":
            population["problem"]["instance"],
            "worker_id":
            population["worker_id"],
            "params": {
                "sample_size": population["population_size"],
                "init": "random:[-5,5]",
                "NGEN": population["params"]["GA"]["iterations"]
            },
            "experiment_id":
            population['experiment']["experiment_id"],
            "algorithm":
            population["algorithm"],
            "alg_params":
            population["params"][population["algorithm"]],
            "dim":
            population["problem"]["dim"],
            "benchmark":
            population["problem"]["function"],
            "fopt":
            population["fopt"],
            "message_counter":
            self.counter,
            "message_id":
            population["message_id"],
            "best_score":
            ("best_score" in population and population["best_score"]) or None
        }
Exemplo n.º 5
0
class ControlledSubject(Observable):
    def __init__(self, enable_queue=True):
        super(ControlledSubject, self).__init__(self._subscribe)

        self.subject = Subject()
        self.enable_queue = enable_queue
        self.queue = [] if enable_queue else None
        self.requested_count = 0
        self.requested_disposable = Disposable.empty()
        self.error = None
        self.has_failed = False
        self.has_completed = False
        self.controlled_disposable = Disposable.empty()

    def _subscribe(self, observer):
        return self.subject.subscribe(observer)

    def on_completed(self):
        check_disposed(self)
        self.has_completed = True

        if not self.enable_queue or not len(self.queue):
            self.subject.on_completed()

    def on_error(self, error):
        check_disposed(self)
        self.has_failed = True
        self.error = error

        if not self.enable_queue or not len(self.queue):
            self.subject.on_error(error)

    def on_next(self, value):
        check_disposed(self)
        has_requested = False

        if not self.requested_count:
            if self.enable_queue:
                self.queue.push(value)
        else:
            if self.requested_count != -1:
                requested_count = self.requested_count
                self.requested_count -= 1
                if requested_count == 0:
                    self.dispose_current_request()

            has_requested = True

        if has_requested:
            self.subject.on_next(value)

    def _process_request(self, number_of_items):
        if self.enable_queue:
            #console.log('queue length', self.queue.length)

            while len(self.queue) >= number_of_items and number_of_items > 0:
                # console.log('number of items', number_of_items)
                self.subject.on_next(self.queue.shift())
                number_of_items -= 1

            if len(self.queue):
                return {
                    "number_of_items": number_of_items,
                    "return_value": True
                }
            else:
                return {
                    "number_of_items": number_of_items,
                    "return_value": False
                }

        if self.has_failed:
            self.subject.on_error(self.error)
            self.controlled_disposable.dispose()
            self.controlled_disposable = Disposable.empty()
        elif self.has_completed:
            self.subject.on_completed()
            self.controlled_disposable.dispose()
            self.controlled_disposable = Disposable.empty()

        return {"number_of_items": number_of_items, "return_value": False}

    def request(self, number):
        check_disposed(self)
        self.dispose_current_request()

        r = self._process_request(number)
        number = r["number_of_items"]
        if not r["return_value"]:
            self.requested_count = number

            def action():
                self.requested_count = 0

            self.requested_disposable = Disposable(action)

            return self.requested_disposable
        else:
            return Disposable.empty()

    def dispose_current_request(self):
        self.requested_disposable.dispose()
        self.requested_disposable = Disposable.empty()

    def dispose(self):
        self.is_disposed = True  # FIXME: something wrong in RxJS?
        self.error = None
        self.subject.dispose()
        self.requested_disposable.dispose()
Exemplo n.º 6
0
class ControlledSubject(Observable):
    def __init__(self, enable_queue=True):
        super(ControlledSubject, self).__init__(self._subscribe)

        self.subject = Subject()
        self.enable_queue = enable_queue
        self.queue = [] if enable_queue else None
        self.requested_count = 0
        self.requested_disposable = Disposable.empty()
        self.error = None
        self.has_failed = False
        self.has_completed = False
        self.controlled_disposable = Disposable.empty()

    def _subscribe(self, observer):
        return self.subject.subscribe(observer)

    def on_completed(self):
        check_disposed(self)
        self.has_completed = True

        if not self.enable_queue or not len(self.queue):
            self.subject.on_completed()

    def on_error(self, error):
        check_disposed(self)
        self.has_failed = True
        self.error = error

        if not self.enable_queue or not len(self.queue):
            self.subject.on_error(error)

    def on_next(self, value):
        check_disposed(self)
        has_requested = False

        if not self.requested_count:
            if self.enable_queue:
                self.queue.push(value)
        else:
            if self.requested_count != -1:
                requested_count = self.requested_count
                self.requested_count -= 1
                if requested_count == 0:
                    self.dispose_current_request()

            has_requested = True

        if has_requested:
            self.subject.on_next(value)

    def _process_request(self, number_of_items):
        if self.enable_queue:
            #console.log('queue length', self.queue.length)

            while len(self.queue) >= number_of_items and number_of_items > 0:
                # console.log('number of items', number_of_items)
                self.subject.on_next(self.queue.shift())
                number_of_items -= 1

            if len(self.queue):
                return { "number_of_items": number_of_items, "return_value": True }
            else:
                return { "number_of_items": number_of_items, "return_value": False }

        if self.has_failed:
            self.subject.on_error(self.error)
            self.controlled_disposable.dispose()
            self.controlled_disposable = Disposable.empty()
        elif self.has_completed:
            self.subject.on_completed()
            self.controlled_disposable.dispose()
            self.controlled_disposable = Disposable.empty()

        return { "number_of_items": number_of_items, "return_value": False }

    def request(self, number):
        check_disposed(self)
        self.dispose_current_request()

        r = self._process_request(number)
        number = r["number_of_items"]
        if not r["return_value"]:
            self.requested_count = number

            def action():
                self.requested_count = 0
            self.requested_disposable = Disposable(action)

            return self.requested_disposable
        else:
            return Disposable.empty()

    def dispose_current_request(self):
        self.requested_disposable.dispose()
        self.requested_disposable = Disposable.empty()

    def dispose(self):
        self.is_disposed = True # FIXME: something wrong in RxJS?
        self.error = None
        self.subject.dispose()
        self.requested_disposable.dispose()
Exemplo n.º 7
0
from rx.subjects import Subject
print("50以下は無効化してしまう壁\n")

stream = Subject()
d = stream.do_action(lambda x: print(x)) \
    .filter(lambda param: param>50) \
    .subscribe(lambda result: print("壁を貫通!{0}のダメージ".format(result)))

# 攻撃!
stream.on_next(0)
stream.on_next(50)
stream.on_next(51)
stream.on_next(49)
stream.on_next(100)
stream.on_next(-50)
stream.dispose()

print("===================")

stream = Subject()
d = stream.do_action(lambda x: print(x)).subscribe()
stream.on_next(0)
stream.on_next(-50)
stream.dispose()
print("===================")
from rx import Observable
from rx.subjects import Subject

# l1 = [1,2,3,4,5]
# l = Subject()
# grouped = l.group_by(lambda x: x % 2).do_action(lambda x: print(x)).subscribe()
class AbstractObservableCollection(ABC, Iterable):
    def __init__(self):
        self._collectionChanges = Subject()
        self.lock = threading.RLock()
        self.is_disposed = False
        self._suppressNotification = False

    @abstractmethod
    def __iter__(self):
        pass

    @abstractmethod
    def __eq__(self, other):
        pass

    @abstractmethod
    def __ne__(self, other):
        pass

    @abstractmethod
    def __contains__(self, item):
        pass

    @abstractmethod
    def __len__(self):
        pass

    @abstractmethod
    def dispose(self):
        """ Clears all the values from the set, unsubscribe all the subscribers and release resources """
        self.check_disposed()
        self._collectionChanges.dispose()
        self.is_disposed = True

    def when_collection_changes(self) -> ObservableBase:
        return Observable.create(lambda obs: self._subscribe(obs))

    def _subscribe(self, observer: Observer) -> Disposable:
        if self.is_disposed:
            return Observable.throw(DisposedException('Trying to access an already disposed object')) \
                .subscribe(observer)
        else:
            return self._collectionChanges.subscribe(observer)

    def _onCollectionChanges(self, item: CollectionChange):
        if not self._suppressNotification:
            try:
                self._collectionChanges.on_next(item)
            except Exception as ex:
                self._collectionChanges.on_error(ex)

    # internal methods
    def _beginSuppressNotification(self) -> None:
        """ Suppresses all change notification from firing """
        self._suppressNotification = True

    def _endSuppressNotification(self) -> None:
        """ Resumes or Begins pushing change notifications for every subsequent change operations made """
        self._suppressNotification = False

    def check_disposed(self):
        if self.is_disposed:
            raise DisposedException(
                'Trying to access an already disposed object')
Exemplo n.º 9
0
class BusManager(object):
    def __init__(self) -> None:

        self.__bus_subject = Subject()
        self.__bus_map: Dict[str, Bus] = dict()
        self.__scanner = TtyScanner()

        x = Observer()

        self.__scanner.added_devices.s
        self.__scanner.added_devices.subscribe(
            lambda device: self.__tty_opened(device))
        self.__scanner.removed_devices.subscribe(self.__tty_closed)
        self.__scanner.removed_devices.subscribe(Observer())
        self.__scanner.scan()

    def __tty_opened(self, device: pyudev.Device) -> None:

        try:
            bus = self.__create_bus(device)
            self.__bus_map[device.device_node] = bus
            self.__bus_subject.on_next(bus)

        except NoPortConfigException as e:
            logging.warning(e)

    def __tty_closed(self, device: pyudev.Device) -> None:

        if device.device_node not in self.__bus_map:
            return

        bus = self.__bus_map.pop(device.device_node)
        bus.close(f"Port {bus.serial.port} disconnected")

    def get_buses(self) -> Observable:

        return rx.concat(rx.from_list(self.__bus_map.values()),
                         self.__bus_subject)

    def dispose(self) -> None:

        self.__scanner.stop()

        for bus in self.__bus_map.values():
            bus.close()

        self.__bus_subject.dispose()

    @staticmethod
    def __create_bus(device: pyudev.Device) -> Bus:

        protocol = portconfig.get_protocol(device)

        serial = Serial(port=device.device_node, baudrate=9600)

        if protocol is Protocol.MODBUS:
            return ModBus(serial)

        if protocol is Protocol.CANBUS:
            return CanBus(serial)

        raise NoPortConfigException(device)