This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
fyjham's profile picture

Too Long Without Yielding & Non-Blocking Inputs

Started by fyjham, 04 February 2013 - 01:36 PM
fyjham #1
Posted 04 February 2013 - 02:36 PM
Title: Too Long Without Yielding & Non-Blocking Inputs

Hi, I've got a few attack turtles at the bottom of a mob farm. I made a little killing script which is something like this (Apologies if I have any typos - my server has no HTTP API so the real script is stuck in the turtle & I often make small LUA mistakes cause I'm more used to other languages):

while true
   if turtle.attack() == false then
	  turtle.sleep(0.2)
   end
   turtle.sleep(0)
end

I plan to get it a bit more complex later, but for now I'm just stuck on why this crashes as too long without yielding. I was of the impression sleep'ing would yield, hence the 0 second sleep, and they crash even when there's no mobs there so they'd be getting 0.2 second sleeps every swing. Is there a simple "yield" function or similar I should be calling? (I cannot find anything akin to it, and all the results from searching just say to add sleeps but I've already done this)

Also, is there a non-blocking version of Os.PullEvent I can use which would just check if the event is ready but not pause waiting for it? I would love to add some sort of "stop" key to the script but using Os.PullEvent in the loop to read the key stops the robot attacking for far too long. As it stands I'm considering using rednet as a form of primitive multi-threading just to get around this (since it's read command has a controllable timeout), but this seems excessive.
Cranium #2
Posted 04 February 2013 - 03:12 PM
Actually, you want to replace turtle.sleep() with just a regular sleep() command. There is no such thing as turtle.sleep() unless you create it.
fyjham #3
Posted 04 February 2013 - 04:19 PM
Oops, that falls under the "retyped and might make mistakes" heading. Thanks for pointing that out, but yeah it's not my main issue since the actual running code is sleep :)/>

Just to update the code without that mistake:

while true
   if turtle.attack() == false then
		  sleep(0.2)
   end
   sleep(0)
end

It does actually run, and it farms mobs just fine. Everything other than the eventual yield crash (which can take quite some time - like easily half an hour or more) works fine.
remiX #4
Posted 04 February 2013 - 05:32 PM
What exactly is it doing when it eventually crashes? Is it attacking a lot then?
fyjham #5
Posted 04 February 2013 - 06:30 PM
No - it's basically doing nothing at that stage. Essentially the turtle sits in front of our mob farm. When you start farming you start it up, turn on the mob system, and it hacks away at all the mobs no problems. We turn off the mob spawning but leave the turtle running (with nothing to kill) and walk off to do something else, then come back a long time later and the app will have crashed listing "Too Long Without Yielding" as the issue. It wouldn't have had any mobs in front of it for the vast majority of that time.

I've never seen it actually crash while it had mobs to kill, although we don't generally run the mob system for hours straight so perhaps it would crash eventually if it was left long enough with things to kill.

There is a chunk-loader in range of it, so there's no chance of the chunk not having been loaded (Plus I suspect we'd have lost the error message if it was).
ChunLing #6
Posted 04 February 2013 - 11:03 PM
If the above is your entire code, then perhaps it should be:
while true do
  if not turtle.attack() then sleep(1) end
end
Still, I don't see how your code could be failing to yield, you've got a sleep() and turtle.attack() call on the loop, there's no way that isn't yielding.
fyjham #7
Posted 05 February 2013 - 04:42 AM
It's my entire code for now yeah - I started with more but I kept cutting it back to the smallest thing I could get the issue from. I intend to expand it significantly once I resolve this.

One thing I did notice playing today was I actually had 1 time today where it crashed within a few seconds of me starting it up. This happened to coincide wih a pretty nasty lag spike on the server… would it be possible that an overloaded server could trigger this kind of issue - server performance issues convincing it the app didn't yield often enough because the processing has slowed down? (Our server does struggle a bit sometimes - server-side block lag etc) Seems a bit far-fetched but I'm grasping at straws here.
KaoS #8
Posted 05 February 2013 - 05:02 AM
heavy lag can cause this. if your server is running too slow to execute the code CC will terminate it

EDIT: I should also mention that it is almost impossible to get this level of lag… what on earth were you doing?
Edited on 05 February 2013 - 04:02 AM
Cranium #9
Posted 05 February 2013 - 06:15 AM
heavy lag can cause this. if your server is running too slow to execute the code CC will terminate it

EDIT: I should also mention that it is almost impossible to get this level of lag… what on earth were you doing?
If it's using tekkit on a less than sufficient machine, there can be quite a large amount of lag. I can personally attest to this, as I have a terrible machine for my private home server.
fyjham #10
Posted 05 February 2013 - 02:19 PM
It's feed-the-beast, not tekkit, but yeah same idea… server's normally fine but occasionally someone does something crazy with one mod or another & causes a pile of lag & we get a nasty spike. The server's definitely a bit under-spec - we don't go in the twilight forest anymore cause it took out the server & we had to delete the entire dimension to get it up and running again :P/>

Guess that must be the cause. Oh well, at least it's not my code… I guess now I can at least know I can't have a stable app running 24/7 on this server. Not the outcome I was hoping for, but thanks for the help. At the very least it's saved me trying to diagnose it for hours :)/>