वायदा के लिए एक ठीक ट्यून्ड थ्रेड पूल को कैसे कॉन्फ़िगर करें?


80

वायदा के लिए स्काला का धागा पूल कितना बड़ा है?

मेरा स्काला एप्लिकेशन कई लाख बनाता है future {}और मुझे आश्चर्य है कि अगर कोई चीज है तो मैं थ्रेड पूल को कॉन्फ़िगर करके उन्हें ऑप्टिमाइज़ कर सकता हूं।

धन्यवाद।


स्लीक 3.0 स्वयं के कनेक्शन और थ्रेडपूल का उपयोग करता है, इसलिए जब हमें स्वयं थ्रेड पूल का प्रबंधन करने की आवश्यकता होती है, तो हमें
इम्प्लांट एक्ज़ीक्यूटेक्स्ट को स् थिक

1
@RahulGulabani, "एसेंशियल स्लीक" पुस्तक से:The reason is that map, flatMap methods of Action allows you to call arbitrary code when joining the actions together. Slick cannot allow that code to be run on its own execution context, because it has no way to know if you are going to tie up Slicks threads for a long time.
srzhio

जवाबों:


90

आप अपने खुद के ExecutionContext को निर्दिष्ट कर सकते हैं कि आपका निहितार्थ वैश्विक निहित ExecutionContext को आयात करने के बजाय में चलेगा।

import java.util.concurrent.Executors
import scala.concurrent._

implicit val ec = new ExecutionContext {
    val threadPool = Executors.newFixedThreadPool(1000)

    def execute(runnable: Runnable) {
        threadPool.submit(runnable)
    }

    def reportFailure(t: Throwable) {}
}

73
शानदार उत्तर, आप एक्ज़ीक्यूशन कोटेक्स्ट पर हेल्पर विधियों का उपयोग करके बॉयलरप्लेट को थोड़ा कम कर सकते हैं जो आपको किसी दिए गए एक्सेक्यूटर से सीधे इंस्टेंट कर सकते हैं। Eg implicit val ec = ExecutionContext.fromExecutor (
Executors.newFixedThreadPool

1
दी यह सब अच्छा है, लेकिन वहाँ implicits.global पर धागे में एक वास्तविक सीमा है? यदि ऐसा है तो application.conf के माध्यम से अक्का की तरह यह विन्यास योग्य है?
निक

6
@ हाँ, implicits.global सीपीयू कोर प्रति केवल 1 धागा है। सीपीयू-बाउंड कार्यों के लिए इष्टतम। लेकिन क्लासिक अवरुद्ध IO (जैसे jdbc) के लिए यह एक प्रदर्शन आपदा है।
बेन हचिसन

2
मुझे इसके इस्तेमाल के बाद थ्रेड पूल को बंद करने के लिए एक कॉल जोड़ने की आवश्यकता थी, या प्रोग्राम कभी समाप्त नहीं होता ... शटडाउन () = थ्रेडपूल.शटडाउन ()
justinhj

2
यह "सामान्य" मामले में बंद क्यों हो जाता है, लेकिन तब नहीं जब हम किसी और चीज को निहित करते हैं?
hbogert

152

यह उत्तर भिक्षुक से है, स्वीकृत उत्तर से एक टिप्पणी है। हालांकि, कोई भी इस महान जवाब को याद कर सकता है इसलिए मैं इसे यहां दोहरा रहा हूं।

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

यदि आपको केवल थ्रेड पूल काउंट को बदलने की आवश्यकता है, तो बस वैश्विक निष्पादक का उपयोग करें और निम्नलिखित सिस्टम गुण पास करें।

-Dscala.concurrent.context.numThreads=8 -Dscala.concurrent.context.maxThreads=8

2
यह एक और अधिक सुंदर समाधान है
बेन हचिसन

मैंने इन दोनों को 5 मान के साथ आज़माया, और मैं अभी भी 8 सूत्र को समवर्ती रूप से देख रहा हूं।
माइक्रोसील

3

स्कैल फ्यूचर में थ्रेडपूल निर्दिष्ट करने का सबसे अच्छा तरीका:

implicit val ec = new ExecutionContext {
      val threadPool = Executors.newFixedThreadPool(conf.getInt("5"));
      override def reportFailure(cause: Throwable): Unit = {};
      override def execute(runnable: Runnable): Unit = threadPool.submit(runnable);
      def shutdown() = threadPool.shutdown();
    }

0
class ThreadPoolExecutionContext(val executionContext: ExecutionContext)

object ThreadPoolExecutionContext {

  val executionContextProvider: ThreadPoolExecutionContext = {
    try {
      val executionContextExecutor: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(25))
      new ThreadPoolExecutionContext(executionContextExecutor)
    } catch {
      case exception: Exception => {
        Log.error("Failed to create thread pool", exception)
        throw exception
      }
    }
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.