Skip to content

Instantly share code, notes, and snippets.

@rickwillcox
Created November 19, 2021 05:36
Show Gist options
  • Save rickwillcox/04971abbe1dd25ff4db57df40452d78c to your computer and use it in GitHub Desktop.
Save rickwillcox/04971abbe1dd25ff4db57df40452d78c to your computer and use it in GitHub Desktop.
#configs - loaded from cfg file
var tcp_listen_port_m : int = 9999 setget m_nosetter
var max_tcp_conns_m : int = 1000 setget m_nosetter
var tcp_conn_timeout_ms_m : int = 2000 setget m_nosetter
var db_hostname_m : String = "localhost" setget m_nosetter
var query_timeout_sec_m : int = 2 setget m_nosetter
var db_max_conns_m : int = 50 setget m_nosetter
var db_conns_bfr_cnt_m : int = 2 setget m_nosetter
var allowed_login_attempts_m : int = 3 setget m_nosetter
var login_timout_sec_m : int setget m_nosetter
#util vars
var tcp_server_m : TCP_Server setget m_nosetter
var tcp_peer_threads_m : Array = [] setget m_nosetter
var query_threads_m : Array = [] setget m_nosetter
var db_mutex_m : Mutex setget m_nosetter
var db_conn_thread_m := Thread.new() setget m_nosetter
#status vars
var running : bool = true setget m_nosetter
var db_conns_m : Array = []setget m_nosetter
var db_qry_cnt_m : int = 0 setget m_nosetter
var db_used_conns_cnt_m : int = 0 setget m_nosetter
var m_tcp_err_m : int setget m_nosetter
func m_db_conn_thread(_no_val_):
while(running):
db_mutex_m.lock()
var db_con_sz = db_conns_m.size()
for idx in db_con_sz:
if !db_conns_m[idx].is_connected_db():
db_conns_m[idx] = null
db_conns_m.remove(idx)
print("db conn expired")
break
db_con_sz = db_conns_m.size()
var total_cons = db_con_sz + db_qry_cnt_m
var needed_conns = db_qry_cnt_m + db_conns_bfr_cnt_m - total_cons
if (total_cons < db_max_conns_m && needed_conns > 0):
var db : MariaDB = m_get_db_conn()
if db != null:
db_conns_m.push_back(db)
db_mutex_m.unlock()
call_deferred("m_db_thread_finished")
func m_get_db_conn() -> MariaDB:
var db := MariaDB.new()
var err = db.set_authtype(MariaDB.AUTH_SRC_SCRIPT, MariaDB.AUTH_TYPE_ED25519, true);
if err :
db = null
push_error("db_auth_err:" + str(err))
else :
err = db.connect_db("localhost", 3306, db_name_m, db_user_m, db_hashed_pwd_m);
if err :
db = null
push_error("db_conn_err:" + str(err))
return db
func m_query(stmt : String, timeout : int) :
db_qry_cnt_m += 1
var db : MariaDB = null
var expire_time : int = 0
if timeout > 0:
expire_time = OS.get_ticks_msec() + timeout * 1000
# stmt = "SET SESSION idle_write_transaction_timeout=" + str(timeout) + \
# ";BEGIN;" + stmt
while db == null && (OS.get_ticks_msec() < expire_time && timeout > 0):
db_mutex_m.lock()
db = db_conns_m.pop_back()
db_used_conns_cnt_m += 1
db_mutex_m.unlock()
if db == null:
pass
elif !db.is_connected_db():
db = null
if db == null:
db_used_conns_cnt_m -= 1
yield(get_tree().create_timer(0.1), "timeout")
var qry_result
if db != null:
qry_result = db.query(stmt)
db_mutex_m.lock()
db_used_conns_cnt_m -= 1
db_conns_m.push_back(db)
db_mutex_m.unlock()
else:
qry_result = {kErrStr: "DB Error!" }
db_qry_cnt_m -= 1
return qry_result
func m_peer_thread(tcp_peer : StreamPeerTCP) -> void:
var id : int = OS.get_thread_caller_id() #get the thread id, returns the same value as thread.get_id()
var ssl_peer := StreamPeerSSL.new()
var err : int = ssl_peer.accept_stream(tcp_peer, ssl_key_m, ssl_cert_m)
if err :
push_error("m_peer_thread - SSL accept stream err code:" + str(err) + " from host:" +
str(tcp_peer.get_connected_host()))
tcp_peer.disconnect_from_host()
call_deferred("m_thread_finished", id)
return
var conn_time : int = OS.get_ticks_msec()
while (ssl_peer.get_status() == StreamPeerSSL.STATUS_HANDSHAKING && OS.get_ticks_msec() -
conn_time < tcp_conn_timeout_ms_m) :
ssl_peer.poll()
var disconnect_peer = false
while (tcp_peer.get_status() == StreamPeerTCP.STATUS_CONNECTED &&
ssl_peer.get_status() == StreamPeerSSL.STATUS_CONNECTED &&
OS.get_ticks_msec() - conn_time < tcp_conn_timeout_ms_m) :
if ssl_peer && ! disconnect_peer:
var ssl_bytes = ssl_peer.get_available_bytes()
if ssl_bytes > 0:
# push_error("m_peer_thread - ssl_bytes:" + str(ssl_bytes))
var data : Dictionary = ssl_peer.get_var()
#get the data and run query
#after running data match and queries
disconnect_peer = true #mbeds_tls does not like the client to disconnect first
ssl_peer.poll()
if ssl_peer.get_status() == StreamPeerSSL.STATUS_CONNECTED:
ssl_peer.disconnect_from_stream()
ssl_peer = null
if tcp_peer.get_status() == StreamPeerTCP.STATUS_CONNECTED:
tcp_peer.disconnect_from_host()
tcp_peer = null
call_deferred("m_thread_finished", id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment