ModelTranslator: RizomUV 间歇 IPC 失败换新实例重试一次(实测 Cut 偶发 2000ms not responding)
This commit is contained in:
@@ -91,16 +91,32 @@ def _call(label, fn, params, timeout=TIMEOUT_S):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
RETRY = 1 # 实例级重试次数:RizomUV IPC 有 2000ms 内部响应窗,偶发 not responding
|
||||||
|
|
||||||
|
|
||||||
def rizom_unwrap(fbx_path, exe, map_res=MAP_RES, padding_px=PADDING_PX):
|
def rizom_unwrap(fbx_path, exe, map_res=MAP_RES, padding_px=PADDING_PX):
|
||||||
"""AutoSeam 全自动切缝 -> Unfold -> Pack -> 覆盖保存 fbx_path。失败抛 RizomError。"""
|
"""AutoSeam 全自动切缝 -> Unfold -> Pack -> 覆盖保存 fbx_path。失败抛 RizomError。
|
||||||
|
间歇性 IPC 失败自动换新实例重试一次。"""
|
||||||
mod = _import_link(exe)
|
mod = _import_link(exe)
|
||||||
|
fbx_abs = os.path.abspath(fbx_path)
|
||||||
|
pad_uv = float(padding_px) / map_res
|
||||||
|
last = None
|
||||||
|
for attempt in range(1 + RETRY):
|
||||||
|
if attempt:
|
||||||
|
print("[警告] RizomUV 第 %d 次失败(%s),换新实例重试" % (attempt, last))
|
||||||
|
try:
|
||||||
|
return _unwrap_once(mod, exe, fbx_abs, map_res, pad_uv)
|
||||||
|
except RizomError as e:
|
||||||
|
last = e
|
||||||
|
raise RizomError("重试后仍失败:%s" % last)
|
||||||
|
|
||||||
|
|
||||||
|
def _unwrap_once(mod, exe, fbx_abs, map_res, pad_uv):
|
||||||
link = mod.CRizomUVLink()
|
link = mod.CRizomUVLink()
|
||||||
try:
|
try:
|
||||||
_call("RunRizomUV", lambda _p: link.RunRizomUV(exePath=exe), None, timeout=60)
|
_call("RunRizomUV", lambda _p: link.RunRizomUV(exePath=exe), None, timeout=60)
|
||||||
except RizomError as e:
|
except RizomError as e:
|
||||||
raise RizomError("RizomUV 启动失败(license/环境):%s" % e)
|
raise RizomError("RizomUV 启动失败(license/环境):%s" % e)
|
||||||
fbx_abs = os.path.abspath(fbx_path)
|
|
||||||
pad_uv = float(padding_px) / map_res
|
|
||||||
try:
|
try:
|
||||||
_call("Load", link.Load, {"File.Path": fbx_abs, "File.XYZ": True})
|
_call("Load", link.Load, {"File.Path": fbx_abs, "File.XYZ": True})
|
||||||
# AutoSeam:MOSAIC(QuasiDevelopable) + 切柄/连洞 + 防重叠后处理
|
# AutoSeam:MOSAIC(QuasiDevelopable) + 切柄/连洞 + 防重叠后处理
|
||||||
|
|||||||
@@ -50,5 +50,27 @@ class TestCall(unittest.TestCase):
|
|||||||
self.assertEqual(ru._call("Ok", lambda p: {"Data": 1}, {}), {"Data": 1})
|
self.assertEqual(ru._call("Ok", lambda p: {"Data": 1}, {}), {"Data": 1})
|
||||||
|
|
||||||
|
|
||||||
|
class TestRetry(unittest.TestCase):
|
||||||
|
def test_second_attempt_succeeds(self):
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def fake_once(*a, **kw):
|
||||||
|
calls.append(1)
|
||||||
|
if len(calls) == 1:
|
||||||
|
raise ru.RizomError("IPC 抖动")
|
||||||
|
|
||||||
|
with mock.patch.object(ru, "_import_link"), \
|
||||||
|
mock.patch.object(ru, "_unwrap_once", side_effect=fake_once):
|
||||||
|
ru.rizom_unwrap("x.fbx", "rizomuv.exe")
|
||||||
|
self.assertEqual(len(calls), 2)
|
||||||
|
|
||||||
|
def test_both_attempts_fail_raises(self):
|
||||||
|
with mock.patch.object(ru, "_import_link"), \
|
||||||
|
mock.patch.object(ru, "_unwrap_once",
|
||||||
|
side_effect=ru.RizomError("持续失败")), \
|
||||||
|
self.assertRaises(ru.RizomError):
|
||||||
|
ru.rizom_unwrap("x.fbx", "rizomuv.exe")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user