gpt4 book ai didi

ajax - Grails/Dojo进度栏从 Controller /服务获取进度

转载 作者:行者123 更新时间:2023-12-02 14:09:15 25 4
gpt4 key购买 nike

目前,我正在使用Grails创建一个基于Web的数据加载应用程序,简而言之,它会使用任意行的excel表格并将其运行在后端系统中,以为测试人员准备数据。

一切工作正常,但我需要做的最后一件事是通知用户(特别是在大型数据文件上)已处理了多少行数据的方法。如果行数超过200,即使该应用仍然运行缓慢,该应用也会显示超时。这是一个问题,因为用户很可能会重新加载文件并弄乱处理……重复的测试数据行将导致一系列下游问题。

我正在玩代码here

<g:actionSubmit action="${appContext}/FileUploader.processFile" value="Upload File" onclick="download()"></g:actionSubmit>

<script type="text/javascript">
dojo.require("dijit.ProgressBar");
dojo.require("dojo.parser");

var i = 0;
function download() {
jsProgress.update({
maximum: 10,
progress: ++i
});
if (i < 10) {
setTimeout(download, 100 + Math.floor(Math.random() * 100));
}
}
</script>

当前在我的 Controller 中,我有一个执行此操作的小方法:
def updateStatus = {
render uploaderService.rowsLoaded / uploaderService.listToSend.size()
}

我似乎无法弄清楚的是调用该方法以获取链接到进度条的百分比的正确方法。 (替换样板的 progress代码。)

我对Java足够了解,但是使它正常工作似乎有点神秘。

无论技术上是否是最佳实践,我都愿意接受任何在此取得进展的想法。我现在只需要一些东西来显示此信息。不一定非要道场,这只是我最初获得最大成功的方向。

最佳答案

首先,您可能要启动后台作业中的进程并将处理消息返回给用户

这是一个如何使用jprogress和executer插件执行此操作的示例。不幸的是,这使用了轮询解决方案。我还没有弄清楚如何使用JMS触发更新。


package jprogressdemo

class Event {

String name
Integer duration = 100
String status = "New"
Integer percentComplete = 0

static mapping = {
cache false
}

static constraints = {
name(size:1..45, unique:true )
duration()
status(size:1..5)
percentComplete()
}
}

控制者
package jprogressdemo

class EventController {

//static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
def progressService
def jmsService


static exposes = ['jms']
static destination = "queue.notification"


def executeAction = {

println "executeAction"

def theEvent = Event.get(params.id)

def duration = theEvent?.duration ?: 10
def name = theEvent?.name.trim() ?: "none"
def startAt = theEvent?.percentComplete ?: 0

toEvent(name,duration,startAt,true)

render "the progress is done"
}

/*
* Start the backgorund task then
* while %complete < 100, query db and update progressbar.
*/

//the progress bar id needs to the same value that's passed into .setProgressBarValue
def backgroundAction = {

println "backgroundAction"

println "isDisabled():${jmsService.isDisabled()}"

def theEvent = Event.get(params.id)

def duration = theEvent?.duration ?: 10
def name = theEvent?.name ?: "none"
def barName = "${name}b"
def percentComplete = theEvent?.percentComplete ?: 0
def lastPct = -1

runAsync {
toEvent(name,duration,percentComplete,false)
}

if (percentComplete > 100) {progressService.setProgressBarValue(barName, 100)}
//can't be factored out because it's this function that
// gets called from the client ????
while(percentComplete <= 100) {
println "percentComplete:${percentComplete}"
if (percentComplete != lastPct ) {
progressService.setProgressBarValue(barName, percentComplete)
lastPct = percentComplete
}
def newEvent = Event.get(params.id)
newEvent.refresh()
percentComplete = theEvent.percentComplete
}


render "the progress is done"
}


//the progress bar id needs to the same value that's passed into .setProgressBarValue
def backgroundProgress = {

def theEvent = Event.get(params.id)

def duration = theEvent?.duration ?: 10
def name = theEvent?.name ?: "none"
def barName = "${name}p"
def percentComplete = theEvent?.percentComplete ?: 0
def lastPct = -1

if (percentComplete > 100) {progressService.setProgressBarValue(barName, 100)}

while(percentComplete <= 100) {
println "percentComplete:${percentComplete}"
if (percentComplete != lastPct ) {
progressService.setProgressBarValue(barName, percentComplete)
lastPct = percentComplete
}
def newEvent = Event.get(params.id)
newEvent.refresh()
percentComplete = theEvent.percentComplete
}

}
/*

% complete needs to get to 101 to avoid infinit loop in polling logic
And you can't go from 0-99 because the progress bar doesn't register a 0

*/

def toEvent(name,duration,startAt,updateBar) {

println "duration:${duration}"
println "name:${name}"
println "startat:${startAt}"

for (int i = startAt; i < 102; i++) {

println "i:${i}"

def theEvent = Event.findByName(name)
theEvent.percentComplete = i
theEvent.save(flush:true)
println "theEvent.percentComplete:${theEvent.percentComplete}"

if(updateBar){
progressService.setProgressBarValue(name, i)
} else {
sendJMSMessage("queue.notification", "${i}")
}

//let's waste some time
for (int a = 0; a < duration; a++) {

for (int b = 0; b < 1000; b++) {

}
}
}
}



def index = {
redirect(action: "list", params: params)
}

def list = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[eventInstanceList: Event.list(params), eventInstanceTotal: Event.count()]
}

def create = {
def eventInstance = new Event()
eventInstance.properties = params
return [eventInstance: eventInstance]
}

def save = {
def eventInstance = new Event(params)
if (eventInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message', args: [message(code: 'event.label', default: 'Event'), eventInstance.id])}"
redirect(action: "show", id: eventInstance.id)
}
else {
render(view: "create", model: [eventInstance: eventInstance])
}
}

def show = {
def eventInstance = Event.get(params.id)
if (!eventInstance) {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "list")
}
else {
[eventInstance: eventInstance]
}
}

def edit = {
def eventInstance = Event.get(params.id)
if (!eventInstance) {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "list")
}
else {
return [eventInstance: eventInstance]
}
}

def update = {
def eventInstance = Event.get(params.id)
if (eventInstance) {
if (params.version) {
def version = params.version.toLong()
if (eventInstance.version > version) {

eventInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'event.label', default: 'Event')] as Object[], "Another user has updated this Event while you were editing")
render(view: "edit", model: [eventInstance: eventInstance])
return
}
}
eventInstance.properties = params
if (!eventInstance.hasErrors() && eventInstance.save(flush: true)) {
flash.message = "${message(code: 'default.updated.message', args: [message(code: 'event.label', default: 'Event'), eventInstance.id])}"
redirect(action: "show", id: eventInstance.id)
}
else {
render(view: "edit", model: [eventInstance: eventInstance])
}
}
else {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "list")
}
}

def delete = {
def eventInstance = Event.get(params.id)
if (eventInstance) {
try {
eventInstance.delete(flush: true)
flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "list")
}
catch (org.springframework.dao.DataIntegrityViolationException e) {
flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "show", id: params.id)
}
}
else {
flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'event.label', default: 'Event'), params.id])}"
redirect(action: "list")
}
}
}

View
<%@ page import="jprogressdemo.Event" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="main" />
<g:javascript library="jquery" plugin="jquery"/>
<jqui:resources/>
<g:set var="entityName" value="${message(code: 'event.label', default: 'Event')}" />
<title><g:message code="default.show.label" args="[entityName]" /></title>
</head>
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
<span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></span>
<span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span>
</div>
<div class="body">
<h1><g:message code="default.show.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<div class="dialog">
<table>
<tbody>

<tr class="prop">
<td valign="top" class="name"><g:message code="event.id.label" default="Id" /></td>

<td valign="top" class="value">${fieldValue(bean: eventInstance, field: "id")}</td>

</tr>

<tr class="prop">
<td valign="top" class="name"><g:message code="event.name.label" default="Name" /></td>

<td valign="top" class="value">${fieldValue(bean: eventInstance, field: "name")}</td>

</tr>

<tr class="prop">
<td valign="top" class="name"><g:message code="event.duration.label" default="Duration" /></td>

<td valign="top" class="value">${fieldValue(bean: eventInstance, field: "duration")}</td>

</tr>

<tr class="prop">
<td valign="top" class="name"><g:message code="event.status.label" default="Status" /></td>

<td valign="top" class="value">${fieldValue(bean: eventInstance, field: "status")}</td>

</tr>

<tr class="prop">
<td valign="top" class="name"><g:message code="event.percentComplete.label" default="Percent Complete" /></td>

<td valign="top" class="value">${fieldValue(bean: eventInstance, field: "percentComplete")}</td>

</tr>

</tbody>
</table>
</div>
<div class="buttons">
<g:form>
<g:hiddenField name="id" value="${eventInstance?.id}" />
<span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
<span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
</g:form>
</div>
<p>
<HR WIDTH="75%" COLOR="#FF0000" SIZE="4"/>
<g:form>
<g:hiddenField name="id" value="${eventInstance?.id}"/>
<g:submitToRemote action="executeAction" name="startButton" value="start...."/>
<g:submitToRemote action="backgroundAction" name="backgroundButton" value="background...."/>
<g:submitToRemote action="backgroundProgress" name="progressButton" value="progress...."/>
</g:form>

<g:jprogress progressId="${eventInstance?.name}" trigger="startButton"/>
<g:jprogress progressId="${eventInstance?.name}b" trigger="backgroundButton"/>
<g:jprogress progressId="${eventInstance?.name}p" trigger="progressButton"/>

</div>
</body>
</html>

关于ajax - Grails/Dojo进度栏从 Controller /服务获取进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7612820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com