2011-06-03 12 views
6

Zamanında sonuçları olan veya olmayan bir hizmeti aramam gerekiyor. Ruby'nin timeout gibi - İşi yapacak standart bir işlevi var mıZamanaşımı olan bir bloğu çalıştırmak için standart bir Scala işlevi var mı?

val result = runWithTimeout(5000, valReturnedOnTimeout) { service.fetch } 

yazabilmek istiyorum?

+0

Ve Evet, Aktörleri kullanmanın bunu çözeceğini biliyorum, ancak bu kadar basit bir sorun için çok fazla zor görünüyor. –

+0

http://stackoverflow.com/q/5797666/132374 –

cevap

6

- in Herhangi bir standart kütüphane fonksiyonunun yokluğu, Futures rotasına gittim.

import scala.concurrent._ 
    import scala.concurrent.duration._ 

    def runWithTimeout[T](timeoutMs: Long)(f: => T) : Option[T] = { 
    Await.result(Future(f), timeMins milliseconds).asInstanceOf[Option[T]] 
    } 

    def runWithTimeout[T](timeoutMs: Long, default: T)(f: => T) : T = { 
    runWithTimeout(timeoutMs)(f).getOrElse(default) 
    } 

Böylece

@Test def test { 
    runWithTimeout(50) { "result" } should equal (Some("result")) 
    runWithTimeout(50) { Thread.sleep(100); "result" } should equal (None) 
    runWithTimeout(50, "no result") { "result" } should equal ("result") 
    runWithTimeout(50, "no result") { Thread.sleep(100); "result" } should equal("no result") 
    } 

Bunun iyi Scala tarzıdır olmadığı konusunda herhangi bir geri bildirim için minnettar olurdum! Henüz söz edilmemiştir

+0

http://stackoverflow.com/questions/6229778 –

1

Yeni bir Konuda başlatabilir ve ardından Thread.join ile bitirmesini bekleyebilirsiniz. Katılmak için bir parametre iletirseniz, en çok milisaniye bekler.

val t = new Thread { 
    override def run() { 
    //... 
    } 
} 
t.start() 
t.join(5000) 
+0

ile ilgili. Teşekkürler ve ayrıca Yürütücüler çerçevesini de kullanabilirim. Ama ben yerleşik ya da deyimsiz bir şeyi kaçırmadığımı kontrol ediyordum. –

2

Kudreti Futures ve onun alarm hile yapmak?

+0

Bunu görmemiştim, teşekkür ederim, ve kesinlikle işlevi yerine getirmenin bir yolu - eğer zaten mevcut değilse. –

5

İlerideki bir

import scala.actors.Futures._ 

val myfuture = 
    future { 
    Thread.sleep(5000) 
    println("<future>") 
    "future " 
} 

awaitAll(300,myfuture) foreach println _ 

kullanmak Ama aynı zamanda Circuit Breaker Pattern bir uygulamasıdır Circuit Breaker for Scala bir göz olabilir. Temel olarak size aşımını kontrol etmek ve bir arıza (readme itibaren)

Kullanımı Scala şöyle harici kaynağa erişen oluşursa ne olur gerektiğini olanak tanır:

diğer cevaplara kredi ile
. . . 
addCircuitBreaker("test", CircuitBreakerConfiguration(timeout=100,failureThreshold=10)) 
. . . 


class Test extends UsingCircuitBreaker { 
    def myMethodWorkingFine = { 
    withCircuitBreaker("test") { 
     . . . 
    } 
    } 

    def myMethodDoingWrong = { 
    withCircuitBreaker("test") { 
     require(false,"FUBAR!!!") 
    } 
    } 
} 
+0

Devre kesicilerden hoşlanıyorum ama standart kütüphanede hiçbir şey yok sanırım. Basit tutmak için Futures'a dayalı bir şeyler yazmayı deneyeceğim. –

+0

, gelecekte iş parçacığını engeller. http://stackoverflow.com/q/5646879/203968 Bu yüzden sizi birçok kez arayan bir müşteri, konularınızı aç bırakabilir. Bu nedenle devre kesici.Aramanın muhtemelen işe yaramayacağını düşündüğünüz yerde "devre kırmak" nerede – oluies

+0

Evet, aramalar web katmanımda olduğundan ve tarayıcı başına bir tane alabileceğimi düşünmem gerekecek. Tarayıcıdan anket almam ve sonunda Executors'ı kullanmam gerekebilir. –

2

şey awaitEither, aktörler paketin Vadeli nesne üzerinde bir yöntemdir.

awaitEither(future{task}, alarm(timeoutPeriod)) 

ve daha sonra bir yöntemde giyinmiş önerildiği gibi:

def runWithTimeout[T](timeoutPeriod: Int, timeoutValue: T)(task: => T) = { 
    awaitEither(future{task}, alarm(timeoutPeriod)) match {case() => timeoutValue case x => x} 
} 

awaitEither böyle örneğin bir şey kullanılabilir, böylece tamamlamak için vadeli bir çift ilk sonucunu döndürür alarmı, herhangi bir tipte bir atama ile atanabilir Birimi, her iki durumda da eşleştirilebilecek bir şey döndürür.

+0

adresindeki istisnalarla başa çıkmak için bu süreyi genişlettim. @ Pr1001 "alarmı" işaretlediğinde ancak muhtemelen alarm için başka bir iş parçacığı başlattığımızı düşünmüştüm - biraz overkill görünüyordu. Olsa da güzel bir kısa ifade için yapar. –

İlgili konular