Page 1 of 1
post json data lag
Posted: Mon Sep 12, 2016 7:09 pm
by Banz
Okay so the problem is whenever I try to send json data server lags for a second (var spike) but the information gets succesfully sent so thats good.
Here is an example code
Syntax: Select all
from commands.say import SayCommand
from messages import SayText2
import json, urllib.request
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.command_string[7:]}
SayText2(whatever["string"]).send(index)
post_request(whatever)
once again thanks in advance
Re: post json data lag
Posted: Mon Sep 12, 2016 8:10 pm
by Ayuto
That's normal. If you don't need the response immediately, you can fix that issue by creating a thread for the request:
https://github.com/Source-Python-Dev-Te ... ick.py#L50
Re: post json data lag
Posted: Mon Sep 12, 2016 8:24 pm
by Banz
Syntax: Select all
from commands.say import SayCommand
from messages import SayText2
from listeners.tick import GameThread
import json, urllib.request
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.command_string[7:]}
SayText2(whatever["string"]).send(index)
t = GameThread(target=post_request(whatever))
t.start()
Is this how it should be done? Still seems to have the spike so I guess not.
Re: post json data lag
Posted: Mon Sep 12, 2016 8:30 pm
by satoon101
Just a small tip, but if you just want the argument string, instead of this:
Syntax: Select all
whatever = {"string": command.command_string[7:]}
use this:
Syntax: Select all
whatever = {"string": command.arg_string}
Re: post json data lag
Posted: Mon Sep 12, 2016 8:33 pm
by Banz
satoon101 wrote:Just a small tip, but if you just want the argument string, instead of this:
Syntax: Select all
whatever = {"string": command.command_string[7:]}
use this:
Syntax: Select all
whatever = {"string": command.arg_string}
Thanks was wondering if there was better way to do that :D
Re: post json data lag
Posted: Mon Sep 12, 2016 8:45 pm
by satoon101
I am no expert with threading, but I think it's something more like:
Syntax: Select all
from commands.say import SayCommand
from messages import SayText2
from listeners.tick import GameThread
import json, urllib.request
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.arg_string}
SayText2(whatever["string"]).send(index)
t = GameThread(target=post_request, args=(whatever, ))
t.start()
Re: post json data lag
Posted: Mon Sep 12, 2016 8:52 pm
by Banz
satoon101 wrote:I am no expert with threading, but I think it's something more like:
Syntax: Select all
from commands.say import SayCommand
from messages import SayText2
from listeners.tick import GameThread
import json, urllib.request
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.arg_string}
SayText2(whatever["string"]).send(index)
t = GameThread(target=post_request, args=(whatever, ))
t.start()
That seemed to do the trick thank you for both of you :)
Re: post json data lag
Posted: Mon Sep 12, 2016 9:40 pm
by Doldol
Be careful, starting a Python thread can introduce lag too. (if someone were to spam !postd, 100% guaranteed the server will start to lag.). My solution would be to create one thread when your plugin starts that you can pass functions to call to, like this:
Syntax: Select all
import time
import threading
import queue
from queue import Queue
from contextlib import suppress
from core import AutoUnload
from hooks.exceptions import except_hooks
from listeners import on_tick_listener_manager
from commands.say import SayCommand
from messages import SayText2
import json, urllib.request
class StoppableSPThread(threading.Thread, AutoUnload):
def __init__(self, accuracy=1, *args, **kwargs):
super().__init__(*args, **kwargs)
self.accuracy = accuracy
on_tick_listener_manager.register_listener(self._tick) # Automatically wake up every tick
self._stop = threading.Event()
def run(self):
while not self.stopped:
try:
self.do()
except Exception:
except_hooks.print_exception()
time.sleep(self.accuracy)
def do(self):
raise NotImplementedError("Override me!")
def _tick(self):
pass
def stop(self):
self._stop.set()
on_tick_listener_manager.unregister_listener(self._tick)
@property
def stopped(self):
return self._stop.is_set()
_unload_instance = stop
class ThreadedCaller(StoppableSPThread):
def __init__(self, *args, **kwargs):
self.queue = Queue()
super().__init__(*args, **kwargs)
def do(self):
with suppress(queue.Empty):
to_call = self.queue.get(block=True, timeout=10)
to_call["func"](*to_call["args"], **to_call["kwargs"])
threaded_caller = ThreadedCaller()
threaded_caller.start()
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.arg_string}
SayText2(whatever["string"]).send(index)
threaded_caller.queue.put_nowait({"func:":post_request, "args":(whatever,), "kwargs":{}})
(Not all of it is tested so it may have some typos.)
Btw, imo it may be a good idea to implement a worker like this in the SP library.
Re: post json data lag
Posted: Mon Sep 12, 2016 10:49 pm
by L'In20Cible
No need to handle the tick listener yourself, simply inherit from
GameThread.
Re: post json data lag
Posted: Tue Jan 17, 2017 7:43 pm
by decompile
Doldol wrote:Be careful, starting a Python thread can introduce lag too. (if someone were to spam !postd, 100% guaranteed the server will start to lag.). My solution would be to create one thread when your plugin starts that you can pass functions to call to, like this:
Syntax: Select all
import time
import threading
import queue
from queue import Queue
from contextlib import suppress
from core import AutoUnload
from hooks.exceptions import except_hooks
from listeners import on_tick_listener_manager
from commands.say import SayCommand
from messages import SayText2
import json, urllib.request
class StoppableSPThread(threading.Thread, AutoUnload):
def __init__(self, accuracy=1, *args, **kwargs):
super().__init__(*args, **kwargs)
self.accuracy = accuracy
on_tick_listener_manager.register_listener(self._tick) # Automatically wake up every tick
self._stop = threading.Event()
def run(self):
while not self.stopped:
try:
self.do()
except Exception:
except_hooks.print_exception()
time.sleep(self.accuracy)
def do(self):
raise NotImplementedError("Override me!")
def _tick(self):
pass
def stop(self):
self._stop.set()
on_tick_listener_manager.unregister_listener(self._tick)
@property
def stopped(self):
return self._stop.is_set()
_unload_instance = stop
class ThreadedCaller(StoppableSPThread):
def __init__(self, *args, **kwargs):
self.queue = Queue()
super().__init__(*args, **kwargs)
def do(self):
with suppress(queue.Empty):
to_call = self.queue.get(block=True, timeout=10)
to_call["func"](*to_call["args"], **to_call["kwargs"])
threaded_caller = ThreadedCaller()
threaded_caller.start()
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.arg_string}
SayText2(whatever["string"]).send(index)
threaded_caller.put_nowait({"func:":post_request, "args":(whatever,), "kwargs":{}})
(Not all of it is tested so it may have some typos.)
Btw, imo it may be a good idea to implement a worker like this in the SP library.
Sorry for bumping older threads,
but Im kinda working with that issue right now.
When I read the code, Im pretty sure that you will get an error since the class "threaded_caller" has no "put_nowait".
Imo it would be good to have an updated and most recent version out of a super GameThread which can be used for http POST or whatever.
Re: post json data lag
Posted: Tue Jan 17, 2017 8:51 pm
by L'In20Cible
decompile wrote:Imo it would be good to have an updated and most recent version out of a super GameThread which can be used for http POST or whatever.
Would be good, yes. How about you propose a PR? :)
Re: post json data lag
Posted: Mon Jan 23, 2017 10:17 pm
by Doldol
decompile wrote:Doldol wrote:Be careful, starting a Python thread can introduce lag too. (if someone were to spam !postd, 100% guaranteed the server will start to lag.). My solution would be to create one thread when your plugin starts that you can pass functions to call to, like this:
Syntax: Select all
import time
import threading
import queue
from queue import Queue
from contextlib import suppress
from core import AutoUnload
from hooks.exceptions import except_hooks
from listeners import on_tick_listener_manager
from commands.say import SayCommand
from messages import SayText2
import json, urllib.request
class StoppableSPThread(threading.Thread, AutoUnload):
def __init__(self, accuracy=1, *args, **kwargs):
super().__init__(*args, **kwargs)
self.accuracy = accuracy
on_tick_listener_manager.register_listener(self._tick) # Automatically wake up every tick
self._stop = threading.Event()
def run(self):
while not self.stopped:
try:
self.do()
except Exception:
except_hooks.print_exception()
time.sleep(self.accuracy)
def do(self):
raise NotImplementedError("Override me!")
def _tick(self):
pass
def stop(self):
self._stop.set()
on_tick_listener_manager.unregister_listener(self._tick)
@property
def stopped(self):
return self._stop.is_set()
_unload_instance = stop
class ThreadedCaller(StoppableSPThread):
def __init__(self, *args, **kwargs):
self.queue = Queue()
super().__init__(*args, **kwargs)
def do(self):
with suppress(queue.Empty):
to_call = self.queue.get(block=True, timeout=10)
to_call["func"](*to_call["args"], **to_call["kwargs"])
threaded_caller = ThreadedCaller()
threaded_caller.start()
def post_request(data):
url = "https://example.com"
req = urllib.request.Request(url)
req.add_header("Content-Type", "application/json; charset=utf-8")
jsondata = json.dumps(data)
jsondataasbytes = jsondata.encode("utf-8")
req.add_header("Content-Length", len(jsondataasbytes))
print(jsondataasbytes)
response = urllib.request.urlopen(req, jsondataasbytes)
@SayCommand("!postd")
def on_say_post(command, index, team):
whatever = {"string": command.arg_string}
SayText2(whatever["string"]).send(index)
threaded_caller.put_nowait({"func:":post_request, "args":(whatever,), "kwargs":{}})
(Not all of it is tested so it may have some typos.)
Btw, imo it may be a good idea to implement a worker like this in the SP library.
Sorry for bumping older threads,
but Im kinda working with that issue right now.
When I read the code, Im pretty sure that you will get an error since the class "threaded_caller" has no "put_nowait".
Imo it would be good to have an updated and most recent version out of a super GameThread which can be used for http POST or whatever.
I'm really late too ^^
You're right, typo:
threaded_caller.put_nowait should be
threaded_caller.queue.put_nowaitI'll correct it if I can still edit the post :3
Re: post json data lag
Posted: Mon Jan 23, 2017 10:21 pm
by Doldol
L'In20Cible wrote:No need to handle the tick listener yourself, simply inherit from
GameThread.
I haven't found __del__ to be very reliable, especially while working with threads.
http://stackoverflow.com/a/1481512I saw bootstrap_inner, but I prefer the finer grained control writing the logic myself gives me while working with threads.