Какой подход к планированию следует использовать для задач ввода-вывода, которые могут блокировать на неопределенный срок до определенной точки? - PullRequest
0 голосов
/ 18 января 2019

Я сомневаюсь, какую стратегию планирования использовать для блокировки задач ввода-вывода в приведенном ниже коде.

Используя метод scheduleWithFixedDelayDispatchTask, кажется, что я буду создавать задачи одну за другой, накапливая задачи, которые могут блокироваться бесконечно. Я не уверен, что использование этой стратегии является правильным.

Используя метод scheduleOnceDispatchTask, я планирую следующую диспетчерскую задачу только после окончания выполнения текущей задачи блокировки, не накапливая выполнения задач, которые могут блокироваться бесконечно.

import java.util.concurrent.TimeUnit

// "io.monix" %% "monix-execution" % "2.3.3"
import monix.execution.schedulers.SchedulerService
import monix.execution.{Cancelable, Scheduler}

import scala.concurrent.duration._

import com.tibco.tibrv.Tibrv

object Temp extends App {

    val dispatchDelay = 1.milli
    val dispatcher = Scheduler.fixedPool(name = "fixed-pool", poolSize = 1)

    sys.addShutdownHook {
      shutdownAndAwaitTermination(dispatcher)
    }

    //scheduleWithFixedDelayDispatchTask()

    scheduleOnceDispatchTask()

    def scheduleWithFixedDelayDispatchTask(): Cancelable = {
      dispatcher.scheduleWithFixedDelay(dispatchDelay, dispatchDelay) {
        dispatch()
      }
    }

    def scheduleOnceDispatchTask(): Cancelable = {
      dispatcher.scheduleOnce(dispatchDelay) {
        dispatch()

        // reschedule the next dispatch task
        scheduleOnceDispatchTask()
      }
    }

    def shutdownAndAwaitTermination(s: SchedulerService)(implicit atMost: FiniteDuration = 10.seconds): Unit = {
      s.shutdown()
      s.awaitTermination(atMost, Scheduler.global)
    }

    def dispatch(): Unit = {
      /*
          Purpose: Dispatch an event; if no event is ready, block.
          Remarks: If the queue is not empty, then this call dispatches the event at the head of the
                   queue, and then returns. If the queue is empty, then this call blocks indefinitely
                   while waiting for the queue to receive an event.
         */
        Tibrv.defaultQueue().dispatch()

        println("dispatching arrived event")
    }

    TimeUnit.SECONDS.sleep(30)
}

Я склонен использовать подход scheduleOnceDispatchTask, но я не знаю, верно ли то, что я считаю, и будут ли проблемы с производительностью, поэтому я здесь для помощи и мнений.

...