Howto do Threading the right way in SP?

Please post any questions about developing your plugin here. Please use the search function before posting!
kalle
Junior Member
Posts: 26
Joined: Sun Jun 26, 2016 9:48 am
Contact:

Howto do Threading the right way in SP?

Postby kalle » Fri Jul 08, 2016 10:59 am

Hey guys,

I really appreciate your help. This forum is very active and because of that I'm getting my little mods better and better. In another thread you mentioned that I should use "Delay" for "outsourcing" things that just need time e.G. 3 seconds in the future.

For my modification I need to calculate a player position to an object over and over again. I use this function for that:

[

Syntax: Select all

]
from listeners import OnTick
@OnTick
def tick_listener():


And yes I'm careful that it's nothing bad at all. So I didn't have a performance problem with this thing. Now: if I use Delay (to respawn a player in e.G. 3 Seconds after death) the OnTick listener stops for at least 3 seconds. That's a problem because I need some math done over and over again otherwise the player would think that something went wrong or does "lag" - even if he can move normally some information messages from the server do not appear at the right time. I tried different things to avoid that (e.G. using queues and make a respawn wave instead of an "normal" respawn).

My question is: how can I do my math stuff indepently from the main thread because the Delay function seems to interrupt my OnTick event. If I just comment out the Delay all is fine.

I know I have to use the GameThread instead of Thread itself but with both (Thread and GameThread) I used to crash the whole server after starting the thread. I also used this tutorial and picked up the neccessary things from it https://pymotw.com/2/threading/

[

Syntax: Select all

]
from listeners.tick import GameThread


Seems I'm to dumb to find a solution myself.
Last edited by kalle on Fri Jul 08, 2016 1:04 pm, edited 1 time in total.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Howto do Threading the right way in SP?

Postby L'In20Cible » Fri Jul 08, 2016 11:13 am

Delay should not freeze your OnTick listener (since that class "rely" on that listener internally), what is your complete code?
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Howto do Threading the right way in SP?

Postby iPlayer » Fri Jul 08, 2016 11:15 am

Could you probably post more code, please?

Because
a) Delay should not freeze your tick listener
b) GameThread.start() should not crash the server

Do you happen to use time.sleep in any way?
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
kalle
Junior Member
Posts: 26
Joined: Sun Jun 26, 2016 9:48 am
Contact:

Re: Howto do Threading the right way in SP?

Postby kalle » Fri Jul 08, 2016 12:30 pm

Mhh okay I'm feeling dumb now. After spending 30 more minutes (and create an example for you) I just solved one of the problems. I just have used "return" instead of "continue" and every time a player died the tick_listener was stopped with "return". And maybe because of that the tick_listener needed some time to work again. After I changed that it's working. What I don't get to work (but it's not heavily needed for now because as I could see with an simple test plugin is that the Delay and Tick_listener is working quite well).

Syntax: Select all

from events import Event
from players.entity import Player
from players.helpers import index_from_userid
from listeners.tick import GameThread

def respawnplayer(userid):
player = Player.from_userid(userid)
if not player:
return
if not player.dead:
return
if player.team not in (2, 3):
return
player.respawn()

@Event('player_death')
def player_death(event):
t = GameThread(target=respawnplayer, args=(event['userid'],))
t.start()


That's how I would start a thread in python (and of course I do in some other projects) but therefore the server is just freezing (no error message) instead of respawn the player immediately. But a respawn isn't needed. Something else would do the same. I am wrong with handling threads in SourcePython?

And no, I'm not using sleep since you've said that this is crap in SP :)
Last edited by kalle on Fri Jul 08, 2016 1:04 pm, edited 1 time in total.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Howto do Threading the right way in SP?

Postby iPlayer » Fri Jul 08, 2016 12:54 pm

Your thread works fine, all checks are done. It crashes specifically on respawning a player from a thread. Somebody smarter than me needs to take a look.
P.S. There's a

Code: Select all

[syntax=py] ... [/syntax]
block to highlight Python code on the forums
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Howto do Threading the right way in SP?

Postby L'In20Cible » Fri Jul 08, 2016 1:03 pm

Waiting a frame is fixing the crash for me:

Syntax: Select all

Delay(0, t.start)


My guess here is a conflict between dead/respawn where the event is called before the dead logic being done executing.
kalle
Junior Member
Posts: 26
Joined: Sun Jun 26, 2016 9:48 am
Contact:

Re: Howto do Threading the right way in SP?

Postby kalle » Fri Jul 08, 2016 1:06 pm

Great,

thank you guys. You rock :)

@iPlayer yea but I'm often use the quick reply and use to write the bb code syntax on my own. But I'll remember for the future and use syntax instead of code for future problems :)
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Howto do Threading the right way in SP?

Postby L'In20Cible » Fri Jul 08, 2016 1:10 pm

I was also able to reproduce the issue you described on the other thread (being stuck on respawn) by respawning instantly into the player_death event. That proves the event is called prior the life state, etc. are set on the player.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Howto do Threading the right way in SP?

Postby iPlayer » Fri Jul 08, 2016 3:55 pm

I'd also like to quote PEP8:
Comparisons to singletons like None should always be done with is or is not , never the equality operators.

about these lines of yours:

Syntax: Select all

player = Player.from_userid(userid)
if not player:
return


Should really be

Syntax: Select all

player = Player.from_userid(userid)
if player is None:
return


Because who knows what else can be casted to False. And you test specifically for None there.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
Ayuto
Project Leader
Posts: 2195
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Howto do Threading the right way in SP?

Postby Ayuto » Fri Jul 08, 2016 5:44 pm

Actually that can never be None. It either raises an error or returns a Player instance.

However, to delay execute something, the Delay class should be used. If you need a real new thread (e.g. to do heavy calculations) GameThread should be used.
kalle
Junior Member
Posts: 26
Joined: Sun Jun 26, 2016 9:48 am
Contact:

Re: Howto do Threading the right way in SP?

Postby kalle » Mon Aug 08, 2016 4:59 pm

I've got some question related to the OnTick listener. I can't find something thats called "deltatime" or "frametime". Is there anything to get the time since the last "tick" happened? Otherwise I will implement something on my own.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Howto do Threading the right way in SP?

Postby L'In20Cible » Mon Aug 08, 2016 5:10 pm

Syntax: Select all

from engines.server import global_vars

print(global_vars.frame_time)

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 143 guests