forked from joey/godottest
163 lines
5.0 KiB
GDScript
163 lines
5.0 KiB
GDScript
extends RefCounted
|
|
class_name GedisDebugger
|
|
|
|
var _gedis: Gedis
|
|
|
|
func _init(gedis: Gedis):
|
|
_gedis = gedis
|
|
if _gedis and _gedis._pubsub:
|
|
_gedis._pubsub.subscribed.connect(_on_subscribed)
|
|
_gedis._pubsub.unsubscribed.connect(_on_unsubscribed)
|
|
|
|
func _on_subscribed(channel: String, subscriber: Object):
|
|
var debugger = Engine.get_singleton("EngineDebugger")
|
|
if debugger and debugger.is_active():
|
|
debugger.send_message("gedis:pubsub_event", ["subscribed", channel, str(subscriber)])
|
|
|
|
func _on_unsubscribed(channel: String, subscriber: Object):
|
|
var debugger = Engine.get_singleton("EngineDebugger")
|
|
if debugger and debugger.is_active():
|
|
debugger.send_message("gedis:pubsub_event", ["unsubscribed", channel, str(subscriber)])
|
|
|
|
static func _ensure_debugger_is_registered():
|
|
if Engine.is_editor_hint():
|
|
return
|
|
|
|
if not Gedis._debugger_registered:
|
|
if Engine.has_singleton("EngineDebugger"):
|
|
var debugger = Engine.get_singleton("EngineDebugger")
|
|
debugger.register_message_capture("gedis", Callable(Gedis, "_on_debugger_message"))
|
|
if debugger.is_active():
|
|
debugger.send_message("gedis:ping", [])
|
|
Gedis._debugger_registered = true
|
|
|
|
static func _on_debugger_message(message: String, data: Array) -> bool:
|
|
# EngineDebugger will call this with the suffix (the part after "gedis:")
|
|
# so message will be e.g. "request_instances" or "request_instance_data".
|
|
if not Engine.has_singleton("EngineDebugger"):
|
|
return false
|
|
|
|
match message:
|
|
"request_instances":
|
|
var instances_data = []
|
|
for instance_info in Gedis.get_all_instances():
|
|
instances_data.append({
|
|
"id": instance_info["id"],
|
|
"name": instance_info["name"]
|
|
})
|
|
var debugger = Engine.get_singleton("EngineDebugger")
|
|
if debugger and debugger.is_active():
|
|
debugger.send_message("gedis:instances_data", instances_data)
|
|
return true
|
|
|
|
"request_instance_data":
|
|
if data.size() < 2:
|
|
return false
|
|
var instance_id = data[0]
|
|
var command = data[1]
|
|
|
|
# Find the target instance in the static registry.
|
|
var target_instance = null
|
|
for inst in Gedis._instances:
|
|
if is_instance_valid(inst) and inst._instance_id == instance_id:
|
|
target_instance = inst
|
|
break
|
|
|
|
if target_instance == null:
|
|
return false
|
|
|
|
var debugger = Engine.get_singleton("EngineDebugger")
|
|
if not debugger or not debugger.is_active():
|
|
return false
|
|
|
|
match command:
|
|
"snapshot":
|
|
var pattern = data[2] if data.size() > 2 else "*"
|
|
var snapshot_data = target_instance.snapshot(pattern)
|
|
debugger.send_message("gedis:snapshot_data", [snapshot_data])
|
|
return true
|
|
"dump":
|
|
if data.size() < 3:
|
|
return false
|
|
var key = data[2]
|
|
var key_value_data = target_instance.dump_key(key)
|
|
debugger.send_message("gedis:key_value_data", [key_value_data])
|
|
return true
|
|
"set":
|
|
if data.size() < 4:
|
|
return false
|
|
var key = data[2]
|
|
var value = data[3]
|
|
target_instance.set_value(key, value)
|
|
var key_value_data = target_instance.dump_key(key)
|
|
debugger.send_message("gedis:key_value_data", [key_value_data])
|
|
return true
|
|
"pubsub":
|
|
var channels = target_instance._pubsub.list_channels()
|
|
var channels_data = {}
|
|
for channel in channels:
|
|
channels_data[channel] = target_instance._pubsub.list_subscribers(channel)
|
|
|
|
var patterns = target_instance._pubsub.list_patterns()
|
|
var patterns_data = {}
|
|
for pattern in patterns:
|
|
patterns_data[pattern] = target_instance._pubsub.list_pattern_subscribers(pattern)
|
|
|
|
debugger.send_message("gedis:pubsub_data", [channels_data, patterns_data])
|
|
return true
|
|
|
|
return false
|
|
|
|
# Debugger-like helpers: type/dump/snapshot
|
|
func type(key: String) -> String:
|
|
if _gedis._expiry._is_expired(key):
|
|
return "none"
|
|
if _gedis._core._store.has(key):
|
|
return "string"
|
|
if _gedis._core._hashes.has(key):
|
|
return "hash"
|
|
if _gedis._core._lists.has(key):
|
|
return "list"
|
|
if _gedis._core._sets.has(key):
|
|
return "set"
|
|
if _gedis._core._sorted_sets.has(key):
|
|
return "zset"
|
|
return "none"
|
|
|
|
func dump(key: String) -> Dictionary:
|
|
var t = type(key)
|
|
if t == "none":
|
|
return {}
|
|
var d: Dictionary = {}
|
|
d["type"] = t
|
|
d["ttl"] = _gedis.ttl(key)
|
|
match t:
|
|
"string":
|
|
d["value"] = _gedis._core._store.get(key, null)
|
|
"hash":
|
|
d["value"] = _gedis._core._hashes.get(key, {}).duplicate(true)
|
|
"list":
|
|
d["value"] = _gedis._core._lists.get(key, []).duplicate()
|
|
"set":
|
|
d["value"] = _gedis._core._sets.get(key, {}).keys()
|
|
"zset":
|
|
var data = _gedis._core._sorted_sets.get(key, {})
|
|
var value = []
|
|
if data.has("sorted_set"):
|
|
# The internal representation is [score, member] but for visualization
|
|
# it's more intuitive to show [member, score].
|
|
for entry in data.sorted_set:
|
|
value.append([entry[1], entry[0]])
|
|
d["value"] = value
|
|
_:
|
|
d["value"] = null
|
|
return d
|
|
|
|
func snapshot(pattern: String = "*") -> Dictionary:
|
|
var out: Dictionary = {}
|
|
for k in _gedis._strings.keys(pattern):
|
|
var key_data = dump(str(k))
|
|
key_data["ttl"] = _gedis._expiry.ttl(str(k))
|
|
out[str(k)] = key_data
|
|
return out
|