Infinite loop in web dev freezes the gateway

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

Yes

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.