I know, it’s the programmer’s fault. But it still shouldn’t take up all the CPU and memory, and cause the gateway to be unresponsive.
Once, I forgot a i+=1. As soon as the web page is opened, the gateway will be frozen.
Maybe it shouldn’t, but I replicated the phenomenon on my server.
path=[]
LineNum=14
i=1
while i<=LineNum:
if i<10:
path.append('[default]Capacity/ZuJian2/currentPlanOutput/L0'+str(i))
else:
path.append('[default]Capacity/ZuJian2/currentPlanOutput/L'+str(i))
i+=1
PlanData=system.tag.readBlocking(path)
PlanOut=[]
PlanHour=[]
i=0
print(PlanOut)
H=system.date.getHour24(system.date.now())
while i<LineNum:
PlanOut.append(PlanData[i].value)
PlanHour.append(int(PlanData[i].value)*H/24)
i+=1
path=[]
i=1
while i<=LineNum:
if i<10:
path.append('[default]Capacity/ZuJian2/currentCompletedOutput/L0'+str(i))
else:
path.append('[default]Capacity/ZuJian2/currentCompletedOutput/L'+str(i))
i+=1
Data=system.tag.readBlocking(path)
RealOut=[]
i=0
while i<LineNum:
RealOut.append(Data[i].value)
i+=1
info=[]
i=0
while i<LineNum:
info.append({"PlanOut":PlanOut[i],"PlanHour":PlanHour[i],"RealOut":RealOut[i]})
i+=1
return {'json': system.util.jsonEncode(info)}
With an infinite loop that's exactly what I would expect. TheGateway is having to allocate more memory each time through the loop. Incrementally it's not a large amount of memory but computers are extremely fast. It makes sense to me that the gateway could use all of the available memory instantly.
Consider using a for loop instead of while. It would certainly avoid infinite loops.
2 Likes
But the gateway should not be unresponsive. What is the use of a server that is not responding.
Not very useful. Be more careful about what you program. You’ve been given a tool with a sharp edge.
3 Likes
The server was just trying to do what you told it. Infinite loops are not the servers fault. Definitely try using for loops as @JordanCClark mentioned, or list comprehensions.
Is there any way to kill a single process instead of the entire gateway? This might make debugging more convenient.
As per @JordanCClark, you should use for loops wherever possible. Consider learning to use list comprehensions and some of python/jython’s built-in functions that manipulate lists. Your entire script can be much shorter and, IMNSHO, more readable:
LineNum=14
fmt1 = '[default]Capacity/ZuJian2/currentPlanOutput/L%02d'
paths1 = [fmt1 % (i+1) for i in range(LineNum)]
fmt2 = '[default]Capacity/ZuJian2/currentCompletedOutput/L%02d'
paths2 = [fmt2 % (i+1) for i in range(LineNum)]
values = [x.value for x in system.tag.readBlocking(paths1+paths2)]
PlanOut = values[:LineNum]
RealOut = values[LineNum:]
H=system.date.getHour24(system.date.now())
PlanHour = [x*H/24 for x in PlanOut]
info = [{'PlanOut': po, 'PlanHour': ph, 'RealOut': ro} for (po, ph, ro) in zip(PlanOut, PlanHour, RealOut)]
return {'json': system.util.jsonEncode(info)}
4 Likes
There is an area on the gateway status page that shows running scripts and allows them to be canceled but I don’t know if WebDev is included in this area. It’s under Status > Diagnostics > Running Scripts.
Thank you for your advice. Regardless of ignition or python, I am a novice(and English…).
In fact, this is exactly the problem. The gateway status page is also unresponsive.
I just think that as a user-oriented server, a single thread should not occupy all resources.
I have tried all of the suggestions, but I've yet to successfully recover from this scenario without a restart. If you're successful, please let me know how you did it.
I have no idea about it. so I replaced all while to for....
I evaluate the number of loops and set the breakout condition. Make sure the loop completes when the code is OK, and can end when the code is wrong.