วิธีใช้ Akka Futures แบบอะซิงโครนัสใน Java

ฉันกำลังโทรในชั้นบริการ Java ที่มีลักษณะเช่นนี้

Future<Object> future = Patterns.ask(myActor, message, timeout);

Response res = (Response) Await.result(future, timeout.duration());

ฉันได้อ่านเอกสารของ Akka แล้วและพบว่าไม่แนะนำให้บล็อกเช่นนี้ ฉันต้องส่งคืนออบเจ็กต์ตอบกลับไปยังวิธีการโทร เป็นไปได้ไหมที่ทำสิ่งนี้แบบอะซิงโครนัสกับ Akka จากบริการ Java ของฉัน ฉันพยายามทำสิ่งนี้โดยใช้วิธี future.onSuccess แต่วิธี onSuccess ไม่อนุญาตให้ส่งคืนค่า ดังนั้นฉันจึงไม่สามารถคืนค่าได้


person cdugga    schedule 20.08.2014    source แหล่งที่มา


คำตอบ (1)


วิธี Akka ในการส่งข้อมูลระหว่างเธรด ซึ่งโดยพื้นฐานแล้วสิ่งที่คุณทำโดยการบล็อกด้านบนคือการสร้างอนาคตหรือส่งข้อความถึงนักแสดง

ตัวอย่างต่อไปนี้นำมาจากเอกสารประกอบของ Akka

final ExecutionContext ec = system.dispatcher();

Future<String> f1 = future(new Callable<String>() {
    public String call() {
        return "Hello" + "World";
    }
}, ec);

Future<Integer> f2 = f1.map(new Mapper<String, Integer>() {
    public Integer apply(String s) {
        return s.length();
    }
}, ec);

f2.onSuccess(new PrintResult<Integer>(), system.dispatcher());

โปรดสังเกตว่าในตัวอย่างนี้ข้อมูลกำลัง 'ส่งคืน' หรือถ้าให้เจาะจงกว่านั้นคือกำลังถูกส่งไปยังหน่วยงานอื่นโดยที่เธรดไม่ต้องบล็อกและรอผลลัพธ์

นี่คือสาเหตุที่ onSuccess ส่งกลับเป็นโมฆะ มันจะถูกใช้ที่จุดสิ้นสุดของห่วงโซ่แห่งอนาคตที่แต่งขึ้น หากจะคืนค่าก็จะเป็นเหมือนแผนที่และจะส่งกลับอนาคตอื่น ซึ่งจะทำให้คุณมีข้อกำหนดในการบล็อกเหมือนกัน

ดังนั้นเพื่อตอบคำถามของคุณไม่ใช่ ไม่มีทางที่จะ 'ส่งคืน' ค่าจากอนาคตแบบอะซิงโครนัสโดยไม่ปิดกั้น แต่คุณควรตรวจสอบว่าทำไมคุณจึงต้องการให้การตอบกลับเป็นเช่นนั้น และดูว่าคุณสามารถย้ายการจัดการการตอบกลับไปที่ onSuccess หรือแผนที่แทนได้หรือไม่ ทางเลือกรองคือการส่งคืน Future[Response] และปล่อยให้ผู้โทรกังวลเกี่ยวกับการผูกมัดอนาคต กรณีที่คุณประสบมักจะเกิดขึ้นเมื่อผสมกระบวนทัศน์ และควรหลีกเลี่ยงอย่างดีที่สุด

person Chris K    schedule 20.08.2014
comment
การโทรที่บล็อกเกิดขึ้นเมื่อผู้ใช้เข้าถึงบริการบนเว็บไซต์ของฉัน ฉันบล็อกเธรดเพราะฉันต้องการให้การตอบสนองต่อคำขอมีข้อมูลบางส่วนเพื่ออัปเดต UI คุณจะแนะนำฉันทำเช่นนี้ได้อย่างไร? - person cdugga; 21.08.2014
comment
โดยทั่วไปรหัส @cdugga GUI ได้รับการออกแบบเพื่อความต่อเนื่อง / การโทรกลับดังนั้นส่วนนั้นควรตรงไปตรงมา เคล็ดลับมักจะอยู่ที่ส่วนของเครือข่าย หากรหัสเครือข่ายได้รับการออกแบบมาให้ไม่ตรงกัน (ใช้ฟิวเจอร์สและนีโอภายใต้ประทุน) ให้บิงโก ไม่เช่นนั้นคุณไม่มีทางเลือก คุณต้องปิดกั้น และนั่นคือสิ่งที่ผมหมายถึงเกี่ยวกับกระบวนทัศน์แบบผสมผสาน รหัสเครือข่าย Java ส่วนใหญ่ได้รับการออกแบบโดยโรงเรียนเก่าให้มีหนึ่งเธรดและบล็อกโมเดล และเมื่อโค้ดประเภทนั้นผสมกับ Akka ก็จะต้องบล็อกที่ไหนสักแห่ง เพียงพยายามย่อให้เล็กสุดและเก็บไว้ในที่หนึ่งหรือสองแห่ง - person Chris K; 21.08.2014
comment
@cdugga เมื่อฉันทำงานกับลูกค้าที่มีรหัสประเภทนี้ และฐานรหัสมีขนาดใหญ่เกินกว่าจะเปลี่ยนไปใช้โซลูชันอะซิงก์ทั้งหมดในครั้งเดียว จากนั้นฉันมักจะเริ่มต้นที่เลเยอร์ต่ำสุดและเริ่มเปลี่ยน DAO ฯลฯ จากการส่งคืน DTO สู่อนาคต[ดีทีโอ] เมื่ออินเทอร์เฟซนี้ข้ามไปยังขอบเขตที่ไม่ใช่อะซิงก์ จะมีบล็อกเกิดขึ้น เมื่อเวลาผ่านไป ฉันจะดันมันให้สูงขึ้นเรื่อยๆ จนกระทั่งถึงรหัสเครือข่าย จากนั้นขั้นตอนสุดท้ายคือการสลับไลบรารีเครือข่ายเป็นอะซิงก์ - person Chris K; 21.08.2014
comment
@cdugga ความเป็นไปได้อื่น ๆ ที่มักจะถูกโจมตีคือที่ที่การเรียก db หรือบริการเว็บใช้การบล็อก api; ในกรณีนั้น สามารถใช้ Future หรือ Actor เพื่อล้อม api นั้นได้ และสามารถกำหนดเธรดเดียวให้ห่างจากเธรดพูลส่วนกลางของ Akka ด้วยเหตุนี้ การทำให้ API การบล็อกดูเหมือนจะไม่บล็อก Akka และหลีกเลี่ยงปัญหาของเธรดพูลส่วนกลางที่อาจทำให้เกิดประสิทธิภาพการทำงานที่ไม่หยุดนิ่งในอนาคตที่รวดเร็ว และในระดับสูงสุด Akka ก็สามารถล็อคได้ - person Chris K; 21.08.2014