كيفية تنفيذ إدراج قاعدة بيانات غير متزامنة في طريقة onReceive الخاصة بالممثل؟

StackOverflow https://stackoverflow.com//questions/25014416

سؤال

لدي تطبيق Play Framework 2 الذي يستخدم Akka أيضًا.انا لدي Actor الذي يتلقى رسائل من نظام بعيد، فإن كمية هذه الرسائل يمكن أن تكون ضخمة جدًا.بعد تلقي الرسالة، أقوم بتسجيل الدخول إلى قاعدة البيانات (باستخدام Ebean ORM المدمج) ثم أواصل معالجتها.لا يهمني مدى سرعة عمل تسجيل قاعدة البيانات هذه، ولكن من المؤكد أنه لا ينبغي أن يمنع المعالجة الإضافية.فيما يلي نموذج تعليمات برمجية مبسطة:

public class MessageReceiver extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof ServerMessage) {
            ServerMessage serverMessage = (ServerMessage) message;
            ServerMessageModel serverMessageModel = new ServerMessageModel(serverMessage);
            serverMessageModel.save();
            //now send the message to another actor for further processing
        } else {
            unhandled(message);
        }
    }
}

كما أفهم، فإن إدراج قاعدة البيانات يعوق هذا الإدراك، لذا فهو لا يلبي احتياجاتي.ولكن لا أستطيع معرفة كيفية جعله فك الحظر.لقد قرأت عن Future الفصل الدراسي، لكن لا يمكنني تشغيله، لأنه يجب أن يُرجع بعض القيمة، و serverMessageModel.save(); عائدات void.أدرك أن كتابة الكثير من الرسائل واحدة تلو الأخرى في قاعدة البيانات أمر غير فعال، ولكن هذه ليست المشكلة في الوقت الحالي.

هل أنا على حق في أن هذا التنفيذ محظور؟إذا كان الأمر كذلك، كيف يمكنني جعله يعمل بشكل غير متزامن؟

هل كانت مفيدة؟

المحلول

إذا كنت ترغب في استخدام Future - قم بإنشاء Akka Future باستخدام فئة قابلة للاستدعاء (فئة مجهولة)، والتي سيقوم تطبيق () الخاص بها بتنفيذ كود حفظ db بالفعل.يمكنك بالفعل وضع كل هذا (الإنشاء المستقبلي والتطبيق () في فئة ServerMessageModel الخاصة بك - ربما نسميها asynchSave ().قد يكون مستقبلك هو المستقبل حيث تكون الحالة نتيجة الحفظ غير المتزامن...

public Future<Status> asyncSave(...) { /* should the params be ServerMessageModel? */
  return future(new Callable<Status>() {
     public Status call() {
        /* do db work here */
     }
 }

في onReceive الخاص بك، يمكنك المضي قدمًا في إخبار الممثل الآخر.ملحوظة:إذا كنت تريد التأكد من أنك ترسل الرسالة إلى الممثل الآخر بعد عودة هذا المستقبل، فيمكنك استخدام onSuccess الخاص بـ Future.

Future<Status> f = serverMessageModel.asyncSave();
f.onSuccess(otherActor.tell(serverMessage, self());

يمكنك أيضًا التعامل مع الفشل ...يرى http://doc.akka.io/docs/akka/2.3.4/java/futures.html لمزيد من التفاصيل.

امل ان يساعد.

نصائح أخرى

الحل المستقبلي يبدو جيدًا بالنسبة لي.لم أستخدم العقود الآجلة من Java، ولكن يمكنك فقط إرجاع عدد صحيح أو سلسلة عشوائية إذا كنت بالتأكيد بحاجة إلى بعض القيمة المرجعة.

الخيار الآخر هو إرسال تلك الرسالة إلى جهة فاعلة أخرى والتي ستقوم بالحفظ في قاعدة البيانات.ثم يجب عليك التأكد من عدم امتلاء صندوق البريد الخاص بهذا الممثل.

هل فكرت عكا الثبات لهذا؟ربما يناسب ذلك حالة الاستخدام الخاصة بك.

حالة الممثل المستمر مع امتداد Martin Krassers akka-persistence ومزود الثبات jdbc الخاص بي akka Persistence jdbc https://github.com/dnvriend/akka-persistence-jdbc

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top