【问题标题】:Long Running Process with Progress Bar Example PlayFramework 2带有进度条示例 PlayFramework 2 的长时间运行过程
【发布时间】:2012-07-09 15:42:04
【问题描述】:

我正在尝试实现一个长时间运行的后台进程,该进程在用户访问页面时产生。我想显示任务的进度,就像在这个例子中一样: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的

【问题讨论】:

    标签: java playframework-2.0 akka


    【解决方案1】:

    在阅读了所有用于 Java 的 Akka 文档http://doc.akka.io/docs/akka/2.0.1/intro/getting-started-first-java.html 之后,我想出了这个似乎运作良好的方法。

    系统首先创建一个唯一的 Actor 来处理“报告”(当加载生成页面时)。这个actor生成一个子actor,它会向父actor报告它的进度。然后通过 JavaScript 轮询父 actor 以获取子线程的状态。

    一旦孩子完成,它就会终止,一旦父母检测到孩子完成,它就会自行终止。

    以下是所有代码,如果我以错误的方式进行此操作,请随时将我撕碎! (可以在 Actors 中存储状态吗?!?)

    控制器代码:

    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>
    
    }
    

    【讨论】:

    • 看起来不错,我试试看。 Play 很棒,但这样的代码示例很少。
    • 我知道,这很令人沮丧!
    • "可以在 Actors 中存储状态吗?!?" Actor 是少数可以存储状态的地方之一。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多