コード例 #1
0
 def __push_prompts(self):
     try:
         item = self.downstream_prompt_queue.get()  # timeout=1)
         self.downstream_prompt_queue.task_done()
         # Todo: Instead, drain the queue and consolidate prompts.
     except Empty:
         self._print_timecheck(
             "timed out getting item from downstream prompt "
             "queue")
         if self.has_been_stopped.is_set():
             return
     else:
         # self.print_timecheck("task done on downstream prompt queue")
         if item is None or self.has_been_stopped.is_set():
             return
         elif isinstance(item, PromptToPull):
             if item.head_notification_id:
                 head_notification_id = item.head_notification_id
             else:
                 head_notification_id = self._get_max_notification_id()
             prompt = RayPrompt(
                 self.process_application.name,
                 self.process_application.pipeline_id,
                 head_notification_id,
             )
         else:
             prompt = item
         # self._print_timecheck('pushing prompt with', prompt.notification_ids)
         prompt_response_ids = []
         # self.print_timecheck("pushing prompts", prompt)
         for downstream_name, ray_process in self.downstream_processes.items(
         ):
             prompt_response_ids.append(ray_process.prompt.remote(prompt))
             if self.has_been_stopped.is_set():
                 return
             # self._print_timecheck("pushed prompt to", downstream_name)
         ray.get(prompt_response_ids)
コード例 #2
0
    def __process_events(self):
        try:
            queue_item = self.upstream_event_queue.get()  # timeout=5)
            self.upstream_event_queue.task_done()
        except Empty:
            if self.has_been_stopped.is_set():
                return
        else:
            if queue_item is None or self.has_been_stopped.is_set():
                return

            for (domain_event, notification_id, upstream_name) in queue_item:
                # print("Processing upstream event:", (domain_event,
                # notification_id, upstream_name))

                new_events, new_records = (), ()
                while not self.has_been_stopped.is_set():
                    try:
                        new_events, new_records = self.do_db_job(
                            method=self.process_application.
                            process_upstream_event,
                            args=(domain_event, notification_id,
                                  upstream_name),
                            kwargs={},
                        )
                        break
                    except Exception as e:
                        print(traceback.format_exc())
                        self._print_timecheck(
                            "Retrying to reprocess event after error:", e)
                        sleep(1)
                        # Todo: Forever? What if this is the wrong event?

                if self.has_been_stopped.is_set():
                    return

                # if new_events:
                #     self._print_timecheck("new events", len(new_events), new_events)

                notifications = ()
                notification_ids = ()
                notifiable_events = [e for e in new_events if e.__notifiable__]
                if len(notifiable_events):
                    if PROMPT_WITH_NOTIFICATION_IDS or PROMPT_WITH_NOTIFICATION_OBJS:
                        manager = self.process_application.event_store.record_manager
                        assert isinstance(manager,
                                          RecordManagerWithNotifications)
                        notification_id_name = manager.notification_id_name
                        notifications = []
                        for record in new_records:
                            if isinstance(
                                    getattr(record, notification_id_name,
                                            None), int):
                                notifications.append(
                                    manager.create_notification_from_record(
                                        record))
                        if len(notifications):
                            head_notification_id = notifications[-1]["id"]
                            if PROMPT_WITH_NOTIFICATION_IDS:
                                notification_ids = self._put_notifications_in_ray_object_store(
                                    notifications)
                                # Clear the notifications, avoid sending with IDs.
                                notifications = ()
                        else:
                            head_notification_id = self._get_max_notification_id(
                            )
                    else:
                        head_notification_id = self._get_max_notification_id()

                    prompt = RayPrompt(
                        self.process_application.name,
                        self.process_application.pipeline_id,
                        head_notification_id,
                        notification_ids,
                        notifications,
                    )

                    # self.print_timecheck(
                    #     "putting prompt on downstream " "prompt queue",
                    #     self.downstream_prompt_queue.qsize(),
                    # )
                    self.downstream_prompt_queue.put(prompt)
                    sleep(MICROSLEEP)
コード例 #3
0
    def test_ray_process(self):
        # Create process with Orders application.
        ray_orders_process = RayProcess.remote(
            application_process_class=Orders,
            infrastructure_class=self.infrastructure_class,
            setup_tables=True,
        )

        # Initialise the ray process.
        ray.get(ray_orders_process.init.remote({}, {}))

        # Create a new order, within the ray process.
        order_id = ray.get(ray_orders_process.call.remote("create_new_order"))

        # Check a UUID is returned.
        self.assertIsInstance(order_id, UUID)

        # Get range of notifications.
        notifications = ray.get(ray_orders_process.get_notifications.remote(1, 1000))
        self.assertIsInstance(notifications, list)
        self.assertEqual(len(notifications), 1)
        self.assertEqual(notifications[0]["id"], 1)

        # Check the range is working.
        notifications = ray.get(ray_orders_process.get_notifications.remote(2, 2))
        self.assertIsInstance(notifications, list)
        self.assertEqual(len(notifications), 0, notifications)

        # Create process with Reservations application.
        ray_reservations_process = RayProcess.remote(
            application_process_class=Reservations,
            infrastructure_class=self.infrastructure_class,
            setup_tables=True,
        )
        # Make the reservations follow the orders.
        ray.get(
            ray_reservations_process.init.remote({"orders": ray_orders_process}, {})
        )

        # Get range of notifications.
        notifications = ray.get(
            ray_reservations_process.get_notifications.remote(1, 1000)
        )
        self.assertIsInstance(notifications, list)
        self.assertEqual(len(notifications), 0)

        # Prompt the process.
        prompt = RayPrompt("orders", 0)
        rayid = ray_reservations_process.prompt.remote(prompt)
        ray.get(rayid)

        # Check a reservation was created.
        retries = 10
        while retries:
            sleep(0.1)
            # Get range of notifications.
            notifications = ray.get(
                ray_reservations_process.get_notifications.remote(1, 1000)
            )
            self.assertIsInstance(notifications, list)

            try:
                self.assertEqual(len(notifications), 1)
            except AssertionError:
                if retries:
                    retries -= 1
                    print("Retrying...", retries)
                else:
                    raise
            else:
                break

        # Add reservations as downstream process of orders.
        ray_orders_process.add_downstream_process.remote(
            "reservations", ray_reservations_process
        )

        # Create a new order, within the ray process.
        order_id = ray.get(ray_orders_process.call.remote("create_new_order"))

        # Get range of notifications.
        notifications = ray.get(ray_orders_process.get_notifications.remote(1, 1000))
        self.assertIsInstance(notifications, list)
        self.assertEqual(len(notifications), 2)

        # Check another reservation was created.
        retries = 10
        while True:
            sleep(0.1)
            # Get a section of the notification log.
            # Get range of notifications.
            notifications = ray.get(
                ray_reservations_process.get_notifications.remote(1, 1000)
            )
            self.assertIsInstance(notifications, list)

            try:
                self.assertEqual(len(notifications), 2)
            except AssertionError:
                if retries:
                    retries -= 1
                    print("Retrying...", retries)
                else:
                    raise
            else:
                break