CC: Tweaked

CC: Tweaked

42M Downloads

Orphaned thread exception

Lupus590 opened this issue ยท 9 comments

commented

Useful information to include:

image

commented

I had this error too, but I'm unable to reproduce it on demand. Unfortunately log_computer_errors was of when it happened, but I'll post logs if it does. I'm going to include much more information than I usually do since this seems like one of those bugs that only happens when doing a handstand in africa during a full moon while closing a browser window.

Running minecraft 1.12.2, forge-1.12.2-14.23.5.2768-universal.jar with these mods:

73b91aff1ad79d6f96e61753cf5962a4cf9af0f222067608575873c6fde0e7d3  mods/FTBLib-5.4.7.0.jar
7695572b3234d90556e9a3d4da6eb27818aeae65b36edb3e48a2178c4c0dac0c  mods/FTBUtilities-5.4.0.124.jar
f32537175f89ddc9890550a158a910e746cac2848db8f6f123865bd4a8a425fb  mods/cc-tweaked-1.12.2-1.89.2.jar
94cc1c05725d81270aee57a3fcce58b726603c272a8d1ad527bbe1379aa85361  mods/plethora-1.12.2-1.2.3.jar

I was running a benchmarking program on an advanced computer, which had a wireless modem attached, and a wired modem attached to a bunch of chests image (was going to make an inventory management system), although the program I was running did not interface with any of these.

this should be the exact program I was running at the time. It's meant to benchmark a library I made that allows connecting to a postgres server through a special-purpose proxy, ws2pg. It uses the default websockets library, and serializes and deserializes with a messagepack library I made, mp. The query function sends off a websocket frame and than waits for a database_message event with the right msgid. A separate "processing" coroutine receives websocket events with websocket.receive() and parsed the data, and queues either a database_message or database_notification, although the latter shouldn't come into play with the timedb script I was running.

I got the error twice. The second time I had run the exact program once already, just after that I ran it again, it immediately showed the OrphanedThreadException error.

Before I got this error and often when trying&failing to reproduce it, I get the error:

Error running computer
Too long without yielding
ComputerCraft may be installed incorrectly

Suspicious things:

  • I'm passing n arguments to parallel.waitForAll, when most uses of it I see in examples have 2 or 3 arguments. When n is 1000 it never seems to finish, while when n is 100 it seems to work fine albeit slowly.
  • By doing so I'm creating n coroutines, and something has to copy every event to every coroutine.
  • The server I'm running on has an old, slow, virtualized CPU

Edit: Fixed image links for the 2nd time

commented
Some notes on @shelvacu's program

One thing it may be worth trying is replacing your explicit Websocket.receive() (i.e. self.internal.receive) calls with a Lua implementation of it. Part of the issue here is that the yield is happening in Java code, which as all sorts of problems.

local function receive(url)
  while true do
    local event, ev_url, contents, is_binary = os.pullEvent("websocket_message")
    if ev_url == url then return contents, is_binary end
  end
end

Obviously this isn't practical in Lupus's case, as they're doing peripheral calls.

When n is 1000 it never seems to finish, while when n is 100 it seems to work fine albeit slowly.

As we're yielding in the Java code, we need to spawn a new thread for each coroutine - so you're creating 1k threads (ouch) and then switching between them 1 million times (1k coroutines, 1k events).

It'd be interesting to see how the performance compares between your current version, MC 1.15 (which redoes how Java-side yields work), and the Lua version of receive as above. The last two should be more efficient, but still not sure it'd work too well.

Also worth noting that CC's event queue has a limit of 256 - meaning it's quite possible that websocket messages are being dropped if you're not processing them fast enough.

Basically the OrphanedThreadException should happen when a yield happens within a Java call and has no way of being resumed (i.e, the coroutine has been garbage collected). It's quite an easy exception to make happen, but it should never be displayed to the user (and on a running coroutine!) - I'm honestly not sure how this is happening.

commented

TLDR: Y'all should update to 1.15, as this is fixed there :p.

commented

I'll update to 1.15 once plethora supports it (and maybe a few other mods).

Starting to consider making a backport fork of CC:T for continued 1.12.2 support.

commented

Sadly this is one of those changes which can't (well, easily) be backported - it's heavily tied to the API changes in 1.15, which break back-compat.

commented

Hoping that these are the right logs
latest.log
debug.log

commented

Logs or it didn't happen.

commented

Can you enable log_computer_errors in the config and try again? Sorry, forget it's not on by default in many configs.

commented

I finally got it to happen again (I still don't know how I'm causing it)

debug.log
latest.log