2017-05-18 7 views
0

Ich arbeite einen gezündeten Service, der einige Aufgaben über run veröffentlichen wird. Der Service sieht so aus:Ist es sicher, in einem Verschluss zu zünden?

public interface MySvc{ 
    public void foSomeJob(); 
} 

public MySvcImpl implements MySvc, Service{ 

    @IgniteInstanceResource 
    private Ignite ignite; 

    public void foSomeJob(){ 
     IgniteCompute compute = ignite.compute(); 
     compute.run(() -> { 
      ignite.binary()   //<----Is it safe? 
        .builder("TYPE"); // What is gonna happen on another node 
      //build binary object and put it into a cache 
     } 
    } 
} 

Die Frage ist, was auf einem anderen Knoten geschehen wird? Wir serialisieren die Ignite Instanz (wirklich ??) und schickten es durch das Netzwerk. Oder wie funktioniert es?

In meinem Fall ist die Ausführung der Aufgabe kritisch ... Also würde ich gerne verstehen, wie es funktioniert, wenn die Aufgabe auf dem anderen Knoten ausgeführt wird?

Vielleicht sollte ich explizit Ignition.ignite(); verwenden?

Antwort

1

Wenn Sie in Ihrem Fall Lambda verwenden, wird dieses entzündete Objekt serialisiert.

Stattdessen können Sie eine Klasse erstellen, um sie als Argument in compute() zu verwenden, und in dieser Klasse die Annotation @IgniteInstanceResource verwenden.

@IgniteInstanceResource-Annotation fügt eine aktuelle ignite-Instanz ein. Im Moment der Ausführung dieser Schließung haben Sie eine gezündete Instanz, die diese Schließung ausführt.

+0

Also ja. 'Ignition.localIgnite' wäre hilfreich. Aber was ist mit 'IgniteCache'? Ist es sicher, es von einem Verschluss zu benutzen? Ich meine, eine 'IgniteCache cache' Referenz in einem closure wenn' affinityRun' zu verwenden? –

+0

Es ist nicht notwendig, in diesem Fall können Sie IgniteCache-Objekt von Ignite von Cache (Name) oder getOrCreateCache-Methoden –

3

Ignite Die Instanz wird in der Tat "serialisiert", und auf dem entfernten Knoten erhalten Sie tatsächlich die Instanz, die für diesen Knoten lokal ist. Ignite wird natürlich nicht physisch über das Netzwerk gesendet.

Mit diesen Worten ist dieser Code korrekt und wird funktionieren. Die Verwendung von lambdas oder anonymen Klassen für Schließungen, die über das Netzwerk gesendet werden, ist jedoch keine sehr gute Übung. Ich würde empfehlen, eine separate Klasse zu erstellen und Ignite mit @IgniteInstanceResource oder Ignition.ignite() zu injizieren. Auf diese Weise haben Sie mehr Kontrolle darüber, was serialisiert und über das Netzwerk gesendet wird. Vom Leistungsstandpunkt aus ist es sicherer und besser.

+0

IgniteInstanceResource in jeder Aufgabe? Ich dachte, es würde Reflektion benutzen. In Fällen mit einer großen Menge an Aufgaben würde es die Leistung beeinträchtigen ... –

+0

BTW, warum nicht 'Ignition.localIgnite()' verwenden? –

+1

Reflection ist nicht langsam, wenn es richtig gemacht wird :) Ignite hat einen Reflection Cache, der sich darum kümmert. 'localIgnite()' ist schwerer, weil es zuerst nach dem Namen suchen muss. Mit 'ignite()' Methode geben Sie es explizit an. –

Verwandte Themen