Подтвердить что ты не робот

Длительный рабочий процесс с индикатором выполнения Пример PlayFramework 2

Я пытаюсь реализовать длительный фоновый процесс, который возникает, когда пользователь посещает страницу. Я хотел бы показать ход выполнения задачи, как в этом примере: http://web.archive.org/web/20130122091205/http://www.lunatech-research.com/archives/2011/10/31/progressbar-jqueryui-websockets-playframework

Кто-нибудь знает учебник для PlayFramework 2.0 (используя встроенную AKKA)? Это для 1.2

4b9b3361

Ответ 1

После прочтения всей документации Akka для Java http://doc.akka.io/docs/akka/2.0.1/intro/getting-started-first-java.html я придумал это, что, похоже, хорошо работает.

Система работает, сначала создавая уникальный Актер для обработки "отчета" (при загрузке страницы сгенерированной страницы). Этот актер порождает ребенка-актера, который сообщает о своем прогрессе родителям. Затем родительский субъект обследуется через JavaScript для статуса дочернего потока.

Как только ребенок закончил, он завершается, и как только родитель обнаруживает, что ребенок закончен, он завершает себя.

Ниже приведен весь код, не стесняйтесь порвать меня, если я ошибаюсь! (Можно ли сохранить состояние в Актерах?!?)

Код контроллера:

public class Application extends Controller {


public static Result generateReport()
{
    //create akka job

    //we should really create the actor with UUID name so that someone can't guess
    //and use the API to view the status of other peoples jobs, it be fairly easy
    //to guess as it goes $a,$b,$c etc...
   ActorRef myActor = Akka.system().actorOf(new Props(MyGeneratorMaster.class));

   System.out.println( myActor.path());
    myActor.tell(new ConfigMessage("blarg message"));

    return ok(generating.render("blarg","title",myActor.path().name()));
}

public static Result status(String uuid)
{
    uuid =  "akka://application/user/"+uuid;
    ActorRef myActor = Akka.system().actorFor(uuid);

    if(myActor.isTerminated())
    {
               return ok("Report Generated - All Actors Terminated") ;
    }
    else
    {

        return async(
                Akka.asPromise(ask(myActor,new StatusMessage(), 3000)).map(
                        new F.Function<Object,Result>() {
                            public Result apply(Object response) {

                                if(response instanceof ResultMessage)
                                {
                                    return ok(((ResultMessage) response).getResult());
                                }
                                return ok(response.toString());
                            }
                        }
                )
        );

    }
}

Мастер-актер:

public class MyGeneratorMaster extends UntypedActor {

    private int completed = 0;

    @Override
    public void postStop() {
        super.postStop();   
        System.out.println("Master Killed");
    }

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof actors.messages.ConfigMessage) {
            ConfigMessage config = (ConfigMessage) message;

            System.out.println("Received Config:" + config.getConfig());

            //Need to spawn child actor here..
            ActorRef child = this.getContext().actorOf(new Props(MyGeneratorChildWorker.class));

            //make the child thread do stuff
            child.tell(new ConfigMessage("doSomething!"));

            child.tell(akka.actor.PoisonPill.getInstance());//kill the child after the work is complete...

        } else if (message instanceof StatusUpdate) {
            System.out.println("Got Status Update");
            completed = ((StatusUpdate) message).getProgress();
        } else if (message instanceof StatusMessage) {
            System.out.println("Got Status Message");
            getSender().tell(new ResultMessage("Status: " + completed + "%"), getSelf());

            if(completed == 100)
            {
                //kill this actor, we're done!
                //could also call stop...
                this.getSelf().tell(akka.actor.PoisonPill.getInstance());
            }
        } else {
            System.out.println("unhandled message"+message.toString());
            unhandled(message);
        }

    }
}

Ребенок Актер:

public class MyGeneratorChildWorker extends UntypedActor {

    @Override
    public void postStop() {
        super.postStop();    
        System.out.println("Child Killed");
    }

    @Override
    public void onReceive(Object message) throws Exception {

        if (message instanceof ConfigMessage) {

            System.out.println("Created Child Worker");

            System.out.println("Doing Work:");
            try {

                for (int i = 0; i <= 100; i++) {


                    //update parent
                    this.context().parent().tell(new StatusUpdate(i));
                    long j = 1;
                     //waste loads of cpu cycles
                    while (j < 1E8) {
                        j = j + 1;
                    }
                }
            } catch (Exception ex) {

            }
            System.out.println("Done Work:");


        } else
            unhandled(message);
    }
}

Страница просмотра с длинным опросом JavaScript:

@(message: String)(title: String)(id: String)@main(title) {

<h2>@message</h2>

        <script type="text/javascript">

            function getPercentage()
            {

                $.ajax({
                    type: "GET",
                    url: "/status/@id",
                    dataType: "html",
                    success: function(html)
                        {
                        $('#status').html(html);


                        }
                });

            }

            $(document).ready(function() {


            setInterval("getPercentage()",100);
            });



        </script>

        <div id="status">

        </div>

}