jerryproxy 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/MANIFEST.in +0 -1
- {jerryproxy-0.1.0/jerryproxy.egg-info → jerryproxy-0.2.0}/PKG-INFO +68 -10
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/README.md +67 -9
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/errors.rst +7 -0
- jerryproxy-0.2.0/docs/source/api_doc/runtime/_logs.rst +14 -0
- jerryproxy-0.2.0/docs/source/api_doc/runtime/_probe.rst +15 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/health.rst +2 -2
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/index.rst +1 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/interfaces.rst +2 -2
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/mihomo.rst +1 -1
- jerryproxy-0.2.0/docs/source/api_doc/runtime/recovery.rst +40 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/index.rst +2 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/installation.rst +1 -1
- jerryproxy-0.2.0/docs/source/runtime_recovery.rst +220 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/anchored.py +4 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/server.py +195 -79
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/config/meta.py +1 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/data/mihomo.json +197 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/data/sing-box.json +1201 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/data/v2ray.json +263 -1
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/errors.py +14 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/lock.py +6 -0
- jerryproxy-0.2.0/jerryproxy/runtime/_logs.py +27 -0
- jerryproxy-0.2.0/jerryproxy/runtime/_probe.py +153 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/health.py +123 -63
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/interfaces.py +12 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/mihomo.py +84 -19
- jerryproxy-0.2.0/jerryproxy/runtime/recovery.py +151 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/session.py +287 -194
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/runner.py +2 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/runtime.py +46 -5
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/manager.py +91 -26
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/transport.py +44 -7
- {jerryproxy-0.1.0 → jerryproxy-0.2.0/jerryproxy.egg-info}/PKG-INFO +68 -10
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy.egg-info/SOURCES.txt +7 -1
- jerryproxy-0.1.0/RELEASE_NOTES.md +0 -111
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/LICENSE +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/THIRD_PARTY_LICENSES.md +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/auto_rst.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/auto_rst_top_index.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/Makefile +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/activation.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/anchored.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/archive.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/archive_preflight.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/catalog.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/download.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/durable.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/identity.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/installation.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/manager.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/model.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/platform.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/recovery.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/registry.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/relay.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/removal.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/backend/state.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/_common.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/_completion.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/clean.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/current.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/install.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/list.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/uninstall.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/use.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/verify.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/backend/which.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/doctor.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/home.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/node/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/node/list.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/self_check.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/server.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/_common.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/add.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/list.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/refresh.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/remove.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/replace.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/show.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/cli/subscription/validate.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/config/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/config/meta.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/data/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/home.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/lock.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/guardian.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/runtime/session.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/backend.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/dependencies.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/environment.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/fixtures.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/processes.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/recovery.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/relay.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/resources.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/result.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/runner.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/runtime.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/selfcheck/subscription.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/audit.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/interfaces.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/manager.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/model.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/redaction.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/storage.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/subscription/transport.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/utils/fs.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc/utils/index.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/api_doc.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/architecture.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/backend_manager.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/conf.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/roadmap.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/docs/source/security.rst +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/__main__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/activation.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/archive.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/archive_preflight.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/catalog.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/download.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/durable.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/identity.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/installation.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/manager.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/model.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/platform.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/recovery.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/registry.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/relay.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/removal.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/backend/state.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/_common.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/_completion.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/clean.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/current.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/install.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/list.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/uninstall.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/use.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/verify.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/backend/which.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/doctor.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/home.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/node/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/node/list.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/self_check.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/_common.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/add.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/list.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/refresh.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/remove.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/replace.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/show.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/cli/subscription/validate.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/config/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/data/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/data/xray.json +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/home.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/runtime/guardian.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/backend.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/dependencies.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/environment.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/fixtures.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/processes.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/recovery.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/relay.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/resources.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/result.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/selfcheck/subscription.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/audit.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/interfaces.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/model.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/redaction.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/subscription/storage.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/utils/__init__.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy/utils/fs.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy.egg-info/dependency_links.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy.egg-info/entry_points.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy.egg-info/requires.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/jerryproxy.egg-info/top_level.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/pyproject.toml +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/requirements-build.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/requirements-dev.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/requirements-doc.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/requirements-test.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/requirements.txt +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/setup.cfg +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/setup.py +0 -0
- {jerryproxy-0.1.0 → jerryproxy-0.2.0}/test/test_structure.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jerryproxy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: An out-of-the-box multi-backend proxy CLI and backend manager.
|
|
5
5
|
Home-page: https://github.com/narugo1992/jerryproxy
|
|
6
6
|
Author: narugo1992
|
|
@@ -46,7 +46,7 @@ switching, and eventually orchestrating multiple external proxy backends. The
|
|
|
46
46
|
PyPI distribution, Python import, GitHub repository, CLI command, and default
|
|
47
47
|
home directory all use the same name: `jerryproxy`.
|
|
48
48
|
|
|
49
|
-
> **0.
|
|
49
|
+
> **0.2.0 release preparation (alpha quality):** the current runtime slice implements bounded
|
|
50
50
|
> `V2RAY_SUBSCRIPTION` ingestion for Base64/plain SS, VMess, VLESS, Trojan,
|
|
51
51
|
> Hysteria2, TUIC, and AnyTLS URI
|
|
52
52
|
> lines and Mihomo/Clash provider YAML, which keeps the supported nodes of a
|
|
@@ -58,7 +58,7 @@ home directory all use the same name: `jerryproxy`.
|
|
|
58
58
|
> credentials and `--bind-all` explicitly selects `0.0.0.0`. Native profiles,
|
|
59
59
|
> other core drivers, and the historical `v2raycli` compatibility layer remain
|
|
60
60
|
> planned. This is the first public release; the `0.x` API and state formats are
|
|
61
|
-
> not stable yet. See the [release notes](https://github.com/narugo1992/jerryproxy/
|
|
61
|
+
> not stable yet. See the [release notes](https://github.com/narugo1992/jerryproxy/releases/latest) for the complete
|
|
62
62
|
> scope, verification evidence, and known limitations.
|
|
63
63
|
|
|
64
64
|
## Current status
|
|
@@ -130,7 +130,8 @@ Python.
|
|
|
130
130
|
|
|
131
131
|
## Installation
|
|
132
132
|
|
|
133
|
-
The
|
|
133
|
+
The source tree is prepared for `0.2.0`; publication is pending. The first
|
|
134
|
+
public release was `0.1.0`. This remains an alpha-quality `0.x` project, so
|
|
134
135
|
the API and managed-state formats may change between releases. Install it from
|
|
135
136
|
PyPI with:
|
|
136
137
|
|
|
@@ -379,7 +380,9 @@ backend registry, packaged catalog access and selection, `filelock`
|
|
|
379
380
|
compatibility, and one lock-consistent installed/active backend inventory. It
|
|
380
381
|
also exercises a complete synthetic backend lifecycle plus install, activation,
|
|
381
382
|
and removal hard-exit recovery in isolated temporary JerryProxy homes without
|
|
382
|
-
changing the configured home.
|
|
383
|
+
changing the configured home. A separate health-worker check spawns the actual
|
|
384
|
+
network worker against a temporary loopback HTTP server, verifies the
|
|
385
|
+
response and confirms cleanup without external traffic. It then streams one fixed 1 MiB Range from
|
|
383
386
|
a pinned public Xray release through each built-in relay. The probe separates
|
|
384
387
|
response-header latency, first-chunk latency, and the speed of the remaining
|
|
385
388
|
chunks, uses a five-second connect/read timeout, and has a parent-enforced
|
|
@@ -486,6 +489,14 @@ prefers GitHub API digests, and reads official checksum text only for legacy
|
|
|
486
489
|
assets where the API has no digest. It never downloads backend archives to
|
|
487
490
|
calculate catalog fingerprints. The updater is not included in the wheel.
|
|
488
491
|
|
|
492
|
+
Scheduled and manual runs first look for an open catalog review. New reviews
|
|
493
|
+
use the exact title `chore(catalog): refresh backend release catalogs` and the
|
|
494
|
+
body marker `<!-- jerryproxy:backend-catalog-refresh -->`; both must match.
|
|
495
|
+
Existing legacy bot reviews are also recognized by title, author, and branch.
|
|
496
|
+
When a review is open, the run comments on the newest matching PR and skips
|
|
497
|
+
refreshing or publishing a branch. After that review is merged or closed, a
|
|
498
|
+
later run may create a new review. Query failures stop the workflow.
|
|
499
|
+
|
|
489
500
|
Relay-health monitoring is also repository infrastructure, not JerryProxy
|
|
490
501
|
runtime behavior. Its 57-site configuration lives in a dedicated
|
|
491
502
|
[Gist](https://gist.github.com/narugo1992/78fb0ee6135fcdf4f0e5c7ec38f2fd59).
|
|
@@ -540,10 +551,57 @@ SOCKS5 listener uses a `socks5h` URL. Backend stdout/stderr are merged into one
|
|
|
540
551
|
bounded live stream, redacted, and labeled only with the backend name
|
|
541
552
|
(`[mihomo]`), never separate stdout/stderr labels; `--backend-log-level`
|
|
542
553
|
defaults to `INFO`. Two consecutive
|
|
543
|
-
failed global health quorums trigger
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
554
|
+
failed global health quorums trigger persistent recovery within the selected
|
|
555
|
+
subscription. Health checks default to 30 seconds, with a confirmation check
|
|
556
|
+
3 seconds after a failure. The backend stays running while nodes are retried
|
|
557
|
+
and hot-reloaded; each recovery round has its own budget and capped backoff.
|
|
558
|
+
Healthy sessions keep their node, listener and credentials, and automatic
|
|
559
|
+
recovery never rewrites the saved preference. Temporary subscription transport
|
|
560
|
+
failures retain verified cache, with separate refresh backoff and Retry-After
|
|
561
|
+
handling. Cache older than 12 hours requests refresh without disqualifying its
|
|
562
|
+
nodes. Control, TLS, authentication, integrity and unclassified failures remain
|
|
563
|
+
terminal. Lifecycle events report starting, degradation, retry attempts,
|
|
564
|
+
refresh outcomes, readiness and completed cleanup. JSONL sends events to stdout
|
|
565
|
+
and ordinary logs to stderr; event visibility is independent of log level.
|
|
566
|
+
Both log producers retain recent redacted diagnostics within a 4 MiB file.
|
|
567
|
+
SIGINT and SIGTERM unwind the foreground session and exit with status 130
|
|
568
|
+
and 143 after cleanup; repeated signals do not interrupt that cleanup. Default
|
|
569
|
+
health requests run in a disposable process that is stopped at the wall deadline,
|
|
570
|
+
so stalled network requests cannot occupy future probe batches. Unconfirmed
|
|
571
|
+
worker cleanup is terminal and retains the home lock; recovery never hides an
|
|
572
|
+
unsafe process state. Existing client connections are not guaranteed to survive
|
|
573
|
+
a node change.
|
|
574
|
+
|
|
575
|
+
Choose `--retry-policy none|fixed|random|adaptive|fallback` in a complete command
|
|
576
|
+
or select the same policy in the guided TTY flow. The default `fallback` uses
|
|
577
|
+
`current:1,adaptive:3,random:all`; `--retry-chain current:1,random:all` selects a
|
|
578
|
+
custom fallback chain. Stages must be unique, counts must be positive integers
|
|
579
|
+
(up to 10,000) or `all`, and `current` permits only `current:1`. Custom chains
|
|
580
|
+
require `fallback`. `none` stops on confirmed failure and disables refresh;
|
|
581
|
+
`fixed` never substitutes a different initial identity; `random` visits nodes
|
|
582
|
+
without replacement; `adaptive` uses aging session-local successes with
|
|
583
|
+
recovery-only exploration. Human and JSONL startup report the chosen policy.
|
|
584
|
+
|
|
585
|
+
Defaults target subscriptions with up to 20 nodes. Recovery first uses short
|
|
586
|
+
3-second health probes, then normal budgets after the fast sweep is exhausted
|
|
587
|
+
so slow usable nodes remain eligible. After 6 seconds spent trying cached
|
|
588
|
+
nodes, the next between-attempt check gives subscription refresh its own
|
|
589
|
+
10-second budget; a large old pool cannot consume that fetch budget. Refresh
|
|
590
|
+
starts at most once per 60 seconds by default, with additional transport
|
|
591
|
+
backoff and Retry-After handling. Changed content is tried without an extra
|
|
592
|
+
round backoff. An in-flight bounded attempt finishes before the refresh check;
|
|
593
|
+
these timings are not a guarantee that an available route exists.
|
|
594
|
+
|
|
595
|
+
Advanced overrides are `--fast-probe-timeout 3`, `--cache-retry-budget 6`,
|
|
596
|
+
`--refresh-timeout 10` and `--refresh-interval 60` (all seconds). Complete
|
|
597
|
+
commands and guided selection share these defaults and overrides. The guided
|
|
598
|
+
flow adds no timing questions; choosing the recommended policy is sufficient.
|
|
599
|
+
|
|
600
|
+
```shell
|
|
601
|
+
jerryproxy server --subscription main --node NODE_ID --retry-policy fixed
|
|
602
|
+
jerryproxy server --subscription main --node NODE_ID --retry-policy fallback \
|
|
603
|
+
--retry-chain current:1,adaptive:3,random:all
|
|
604
|
+
```
|
|
547
605
|
|
|
548
606
|
Nodes are listed with the label their provider put in the URI fragment, so
|
|
549
607
|
several endpoints of one protocol stay distinguishable. That fragment is
|
|
@@ -627,7 +685,7 @@ tampering and is never repaired automatically.
|
|
|
627
685
|
- [x] Implement managed `V2RAY_SUBSCRIPTION` fetch, private state, and URI
|
|
628
686
|
inventory for every encrypted protocol the qualified backend accepts.
|
|
629
687
|
- [x] Implement the Mihomo foreground driver, loopback listener, merged named
|
|
630
|
-
backend stream, and
|
|
688
|
+
backend stream, and persistent health recovery with bounded rounds.
|
|
631
689
|
- [ ] Implement durable controller operations, measurements, and service
|
|
632
690
|
integration.
|
|
633
691
|
- [ ] Preserve documented `v2raycli` inputs through deprecated aliases.
|
|
@@ -5,7 +5,7 @@ switching, and eventually orchestrating multiple external proxy backends. The
|
|
|
5
5
|
PyPI distribution, Python import, GitHub repository, CLI command, and default
|
|
6
6
|
home directory all use the same name: `jerryproxy`.
|
|
7
7
|
|
|
8
|
-
> **0.
|
|
8
|
+
> **0.2.0 release preparation (alpha quality):** the current runtime slice implements bounded
|
|
9
9
|
> `V2RAY_SUBSCRIPTION` ingestion for Base64/plain SS, VMess, VLESS, Trojan,
|
|
10
10
|
> Hysteria2, TUIC, and AnyTLS URI
|
|
11
11
|
> lines and Mihomo/Clash provider YAML, which keeps the supported nodes of a
|
|
@@ -17,7 +17,7 @@ home directory all use the same name: `jerryproxy`.
|
|
|
17
17
|
> credentials and `--bind-all` explicitly selects `0.0.0.0`. Native profiles,
|
|
18
18
|
> other core drivers, and the historical `v2raycli` compatibility layer remain
|
|
19
19
|
> planned. This is the first public release; the `0.x` API and state formats are
|
|
20
|
-
> not stable yet. See the [release notes](https://github.com/narugo1992/jerryproxy/
|
|
20
|
+
> not stable yet. See the [release notes](https://github.com/narugo1992/jerryproxy/releases/latest) for the complete
|
|
21
21
|
> scope, verification evidence, and known limitations.
|
|
22
22
|
|
|
23
23
|
## Current status
|
|
@@ -89,7 +89,8 @@ Python.
|
|
|
89
89
|
|
|
90
90
|
## Installation
|
|
91
91
|
|
|
92
|
-
The
|
|
92
|
+
The source tree is prepared for `0.2.0`; publication is pending. The first
|
|
93
|
+
public release was `0.1.0`. This remains an alpha-quality `0.x` project, so
|
|
93
94
|
the API and managed-state formats may change between releases. Install it from
|
|
94
95
|
PyPI with:
|
|
95
96
|
|
|
@@ -338,7 +339,9 @@ backend registry, packaged catalog access and selection, `filelock`
|
|
|
338
339
|
compatibility, and one lock-consistent installed/active backend inventory. It
|
|
339
340
|
also exercises a complete synthetic backend lifecycle plus install, activation,
|
|
340
341
|
and removal hard-exit recovery in isolated temporary JerryProxy homes without
|
|
341
|
-
changing the configured home.
|
|
342
|
+
changing the configured home. A separate health-worker check spawns the actual
|
|
343
|
+
network worker against a temporary loopback HTTP server, verifies the
|
|
344
|
+
response and confirms cleanup without external traffic. It then streams one fixed 1 MiB Range from
|
|
342
345
|
a pinned public Xray release through each built-in relay. The probe separates
|
|
343
346
|
response-header latency, first-chunk latency, and the speed of the remaining
|
|
344
347
|
chunks, uses a five-second connect/read timeout, and has a parent-enforced
|
|
@@ -445,6 +448,14 @@ prefers GitHub API digests, and reads official checksum text only for legacy
|
|
|
445
448
|
assets where the API has no digest. It never downloads backend archives to
|
|
446
449
|
calculate catalog fingerprints. The updater is not included in the wheel.
|
|
447
450
|
|
|
451
|
+
Scheduled and manual runs first look for an open catalog review. New reviews
|
|
452
|
+
use the exact title `chore(catalog): refresh backend release catalogs` and the
|
|
453
|
+
body marker `<!-- jerryproxy:backend-catalog-refresh -->`; both must match.
|
|
454
|
+
Existing legacy bot reviews are also recognized by title, author, and branch.
|
|
455
|
+
When a review is open, the run comments on the newest matching PR and skips
|
|
456
|
+
refreshing or publishing a branch. After that review is merged or closed, a
|
|
457
|
+
later run may create a new review. Query failures stop the workflow.
|
|
458
|
+
|
|
448
459
|
Relay-health monitoring is also repository infrastructure, not JerryProxy
|
|
449
460
|
runtime behavior. Its 57-site configuration lives in a dedicated
|
|
450
461
|
[Gist](https://gist.github.com/narugo1992/78fb0ee6135fcdf4f0e5c7ec38f2fd59).
|
|
@@ -499,10 +510,57 @@ SOCKS5 listener uses a `socks5h` URL. Backend stdout/stderr are merged into one
|
|
|
499
510
|
bounded live stream, redacted, and labeled only with the backend name
|
|
500
511
|
(`[mihomo]`), never separate stdout/stderr labels; `--backend-log-level`
|
|
501
512
|
defaults to `INFO`. Two consecutive
|
|
502
|
-
failed global health quorums trigger
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
513
|
+
failed global health quorums trigger persistent recovery within the selected
|
|
514
|
+
subscription. Health checks default to 30 seconds, with a confirmation check
|
|
515
|
+
3 seconds after a failure. The backend stays running while nodes are retried
|
|
516
|
+
and hot-reloaded; each recovery round has its own budget and capped backoff.
|
|
517
|
+
Healthy sessions keep their node, listener and credentials, and automatic
|
|
518
|
+
recovery never rewrites the saved preference. Temporary subscription transport
|
|
519
|
+
failures retain verified cache, with separate refresh backoff and Retry-After
|
|
520
|
+
handling. Cache older than 12 hours requests refresh without disqualifying its
|
|
521
|
+
nodes. Control, TLS, authentication, integrity and unclassified failures remain
|
|
522
|
+
terminal. Lifecycle events report starting, degradation, retry attempts,
|
|
523
|
+
refresh outcomes, readiness and completed cleanup. JSONL sends events to stdout
|
|
524
|
+
and ordinary logs to stderr; event visibility is independent of log level.
|
|
525
|
+
Both log producers retain recent redacted diagnostics within a 4 MiB file.
|
|
526
|
+
SIGINT and SIGTERM unwind the foreground session and exit with status 130
|
|
527
|
+
and 143 after cleanup; repeated signals do not interrupt that cleanup. Default
|
|
528
|
+
health requests run in a disposable process that is stopped at the wall deadline,
|
|
529
|
+
so stalled network requests cannot occupy future probe batches. Unconfirmed
|
|
530
|
+
worker cleanup is terminal and retains the home lock; recovery never hides an
|
|
531
|
+
unsafe process state. Existing client connections are not guaranteed to survive
|
|
532
|
+
a node change.
|
|
533
|
+
|
|
534
|
+
Choose `--retry-policy none|fixed|random|adaptive|fallback` in a complete command
|
|
535
|
+
or select the same policy in the guided TTY flow. The default `fallback` uses
|
|
536
|
+
`current:1,adaptive:3,random:all`; `--retry-chain current:1,random:all` selects a
|
|
537
|
+
custom fallback chain. Stages must be unique, counts must be positive integers
|
|
538
|
+
(up to 10,000) or `all`, and `current` permits only `current:1`. Custom chains
|
|
539
|
+
require `fallback`. `none` stops on confirmed failure and disables refresh;
|
|
540
|
+
`fixed` never substitutes a different initial identity; `random` visits nodes
|
|
541
|
+
without replacement; `adaptive` uses aging session-local successes with
|
|
542
|
+
recovery-only exploration. Human and JSONL startup report the chosen policy.
|
|
543
|
+
|
|
544
|
+
Defaults target subscriptions with up to 20 nodes. Recovery first uses short
|
|
545
|
+
3-second health probes, then normal budgets after the fast sweep is exhausted
|
|
546
|
+
so slow usable nodes remain eligible. After 6 seconds spent trying cached
|
|
547
|
+
nodes, the next between-attempt check gives subscription refresh its own
|
|
548
|
+
10-second budget; a large old pool cannot consume that fetch budget. Refresh
|
|
549
|
+
starts at most once per 60 seconds by default, with additional transport
|
|
550
|
+
backoff and Retry-After handling. Changed content is tried without an extra
|
|
551
|
+
round backoff. An in-flight bounded attempt finishes before the refresh check;
|
|
552
|
+
these timings are not a guarantee that an available route exists.
|
|
553
|
+
|
|
554
|
+
Advanced overrides are `--fast-probe-timeout 3`, `--cache-retry-budget 6`,
|
|
555
|
+
`--refresh-timeout 10` and `--refresh-interval 60` (all seconds). Complete
|
|
556
|
+
commands and guided selection share these defaults and overrides. The guided
|
|
557
|
+
flow adds no timing questions; choosing the recommended policy is sufficient.
|
|
558
|
+
|
|
559
|
+
```shell
|
|
560
|
+
jerryproxy server --subscription main --node NODE_ID --retry-policy fixed
|
|
561
|
+
jerryproxy server --subscription main --node NODE_ID --retry-policy fallback \
|
|
562
|
+
--retry-chain current:1,adaptive:3,random:all
|
|
563
|
+
```
|
|
506
564
|
|
|
507
565
|
Nodes are listed with the label their provider put in the URI fragment, so
|
|
508
566
|
several endpoints of one protocol stay distinguishable. That fragment is
|
|
@@ -586,7 +644,7 @@ tampering and is never repaired automatically.
|
|
|
586
644
|
- [x] Implement managed `V2RAY_SUBSCRIPTION` fetch, private state, and URI
|
|
587
645
|
inventory for every encrypted protocol the qualified backend accepts.
|
|
588
646
|
- [x] Implement the Mihomo foreground driver, loopback listener, merged named
|
|
589
|
-
backend stream, and
|
|
647
|
+
backend stream, and persistent health recovery with bounded rounds.
|
|
590
648
|
- [ ] Implement durable controller operations, measurements, and service
|
|
591
649
|
integration.
|
|
592
650
|
- [ ] Preserve documented `v2raycli` inputs through deprecated aliases.
|
|
@@ -115,6 +115,13 @@ SubscriptionFetchError
|
|
|
115
115
|
.. autoclass:: SubscriptionFetchError
|
|
116
116
|
|
|
117
117
|
|
|
118
|
+
SubscriptionTransportError
|
|
119
|
+
-----------------------------------------------------
|
|
120
|
+
|
|
121
|
+
.. autoclass:: SubscriptionTransportError
|
|
122
|
+
:members: __init__
|
|
123
|
+
|
|
124
|
+
|
|
118
125
|
SubscriptionParseError
|
|
119
126
|
-----------------------------------------------------
|
|
120
127
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
:orphan:
|
|
2
|
+
|
|
3
|
+
jerryproxy.runtime.\_logs
|
|
4
|
+
========================================================
|
|
5
|
+
|
|
6
|
+
.. currentmodule:: jerryproxy.runtime._logs
|
|
7
|
+
|
|
8
|
+
.. automodule:: jerryproxy.runtime._logs
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
append\_recent
|
|
12
|
+
-----------------------------------------------------
|
|
13
|
+
|
|
14
|
+
.. autofunction:: append_recent
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
:orphan:
|
|
2
|
+
|
|
3
|
+
jerryproxy.runtime.\_probe
|
|
4
|
+
========================================================
|
|
5
|
+
|
|
6
|
+
.. currentmodule:: jerryproxy.runtime._probe
|
|
7
|
+
|
|
8
|
+
.. automodule:: jerryproxy.runtime._probe
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
ProbeProcess
|
|
12
|
+
-----------------------------------------------------
|
|
13
|
+
|
|
14
|
+
.. autoclass:: ProbeProcess
|
|
15
|
+
:members: __init__,close,check
|
|
@@ -45,14 +45,14 @@ ConnectivityProbe
|
|
|
45
45
|
-----------------------------------------------------
|
|
46
46
|
|
|
47
47
|
.. autoclass:: ConnectivityProbe
|
|
48
|
-
:members: __init__,check
|
|
48
|
+
:members: __init__,check,close
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
RecoveryPolicy
|
|
52
52
|
-----------------------------------------------------
|
|
53
53
|
|
|
54
54
|
.. autoclass:: RecoveryPolicy
|
|
55
|
-
:members:
|
|
55
|
+
:members: retry_policy,retry_chain,confirmation_delay,refresh_interval,fast_probe_timeout,cache_retry_budget,refresh_timeout,health_interval,recovery_deadline,refresh_on_failure,refresh_stale_seconds,__post_init__
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
RecoveryDeadline
|
|
@@ -17,11 +17,11 @@ LoadedNodes
|
|
|
17
17
|
-----------------------------------------------------
|
|
18
18
|
|
|
19
19
|
.. autoclass:: LoadedNodes
|
|
20
|
-
:members: accepted,selected,bypassing
|
|
20
|
+
:members: accepted,selected,bypassing,identities
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
RuntimeDriver
|
|
24
24
|
-----------------------------------------------------
|
|
25
25
|
|
|
26
26
|
.. autoclass:: RuntimeDriver
|
|
27
|
-
:members: name,projection,loaded_nodes,create_process,wait_ready,stop
|
|
27
|
+
:members: name,projection,loaded_nodes,reload_provider,create_process,wait_ready,stop
|
|
@@ -52,7 +52,7 @@ MihomoDriver
|
|
|
52
52
|
-----------------------------------------------------
|
|
53
53
|
|
|
54
54
|
.. autoclass:: MihomoDriver
|
|
55
|
-
:members: __init__,name,projection,loaded_nodes,create_process,wait_ready,stop
|
|
55
|
+
:members: __init__,name,projection,loaded_nodes,reload_provider,create_process,wait_ready,stop
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
MihomoProcess
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
jerryproxy.runtime.recovery
|
|
2
|
+
========================================================
|
|
3
|
+
|
|
4
|
+
.. currentmodule:: jerryproxy.runtime.recovery
|
|
5
|
+
|
|
6
|
+
.. automodule:: jerryproxy.runtime.recovery
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
DEFAULT\_RETRY\_CHAIN
|
|
10
|
+
-----------------------------------------------------
|
|
11
|
+
|
|
12
|
+
.. autodata:: DEFAULT_RETRY_CHAIN
|
|
13
|
+
:no-value:
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
RETRY\_POLICIES
|
|
17
|
+
-----------------------------------------------------
|
|
18
|
+
|
|
19
|
+
.. autodata:: RETRY_POLICIES
|
|
20
|
+
:no-value:
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
RetrySchedule
|
|
24
|
+
-----------------------------------------------------
|
|
25
|
+
|
|
26
|
+
.. autoclass:: RetrySchedule
|
|
27
|
+
:members: __init__,begin_sweep,update,record,wait_seconds,next
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
RetryBackoff
|
|
31
|
+
-----------------------------------------------------
|
|
32
|
+
|
|
33
|
+
.. autoclass:: RetryBackoff
|
|
34
|
+
:members: __init__,healthy,failed
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
parse\_retry\_chain
|
|
38
|
+
-----------------------------------------------------
|
|
39
|
+
|
|
40
|
+
.. autofunction:: parse_retry_chain
|
|
@@ -5,7 +5,7 @@ JerryProxy is a Python 3.7+ multi-backend proxy CLI and backend manager.
|
|
|
5
5
|
|
|
6
6
|
.. warning::
|
|
7
7
|
|
|
8
|
-
JerryProxy 0.
|
|
8
|
+
JerryProxy 0.2.0 is prepared for release; publication is pending. The current
|
|
9
9
|
runtime slice accepts bounded ``V2RAY_SUBSCRIPTION`` URI sources and
|
|
10
10
|
Mihomo/Clash proxy-provider YAML for the encrypted protocols the qualified
|
|
11
11
|
backend accepts, and runs Mihomo 1.19.29 in the foreground. Native profiles,
|
|
@@ -21,4 +21,5 @@ JerryProxy is a Python 3.7+ multi-backend proxy CLI and backend manager.
|
|
|
21
21
|
architecture
|
|
22
22
|
security
|
|
23
23
|
roadmap
|
|
24
|
+
runtime_recovery
|
|
24
25
|
api_doc
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Installation
|
|
2
2
|
============
|
|
3
3
|
|
|
4
|
-
JerryProxy 0.
|
|
4
|
+
JerryProxy 0.2.0 is prepared for release; publication is pending. It supports Python
|
|
5
5
|
3.7 and newer and is distributed as a pure-Python wheel. The ``0.x`` API and
|
|
6
6
|
managed-state formats are not stable yet.
|
|
7
7
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Persistent recovery implementation contract
|
|
2
|
+
===========================================
|
|
3
|
+
|
|
4
|
+
This contract defines persistent recovery and its merge acceptance criteria.
|
|
5
|
+
It implements the maintainer's
|
|
6
|
+
Chinese design document, revision 8, dated 2026-09-21.
|
|
7
|
+
|
|
8
|
+
Inputs and boundaries
|
|
9
|
+
---------------------
|
|
10
|
+
|
|
11
|
+
The caller explicitly selects one subscription and one initial node. Recovery
|
|
12
|
+
must never leave that subscription, change its saved preference, interpret
|
|
13
|
+
protocol credentials, or replace the existing runtime-driver boundary.
|
|
14
|
+
Healthy sessions keep their current node; exploration and exit-IP changes
|
|
15
|
+
are permitted only during recovery. There is no automatic failback.
|
|
16
|
+
|
|
17
|
+
Startup and periodic outages use the same recovery path. Transient outages
|
|
18
|
+
have no session lifetime limit. Each probe, reload, refresh, cleanup and retry
|
|
19
|
+
round remains bounded. A round deadline preserves pending candidates rather
|
|
20
|
+
than repeatedly starving the tail of a large subscription.
|
|
21
|
+
|
|
22
|
+
Fast recovery defaults
|
|
23
|
+
----------------------
|
|
24
|
+
|
|
25
|
+
For subscriptions with up to 20 nodes, the first recovery sweep uses a
|
|
26
|
+
three-second health budget per candidate. After six seconds on cached
|
|
27
|
+
candidates, the next between-attempt check gives a source refresh an
|
|
28
|
+
independent ten-second budget. An in-flight bounded reload/probe completes
|
|
29
|
+
before this check; six seconds is a scheduling threshold, not a hard wall.
|
|
30
|
+
Refresh is checked between attempts and rounds, never only against the
|
|
31
|
+
remaining round budget. Its default minimum interval is 60 seconds, with
|
|
32
|
+
transport backoff and Retry-After still enforced. Changed source content is
|
|
33
|
+
eligible immediately without an extra round backoff. An exhausted fast sweep
|
|
34
|
+
falls back to normal probe budgets so slow usable nodes are not excluded.
|
|
35
|
+
Healthy sessions retain the existing check interval and never explore.
|
|
36
|
+
|
|
37
|
+
These defaults target fast restoration rather than an optimal-node search.
|
|
38
|
+
Verification compares 1, 5, 10 and 20-node replacement and partial-outage
|
|
39
|
+
scenarios, including slow usable nodes, unchanged/failed refresh, deadline
|
|
40
|
+
exhaustion and CLI/guided default and override parity. Simulated timing is
|
|
41
|
+
not a public-network latency guarantee. Safety and cleanup remain terminal
|
|
42
|
+
boundaries. Advanced timing options must not add guided questions.
|
|
43
|
+
|
|
44
|
+
``--fast-probe-timeout`` (3), ``--cache-retry-budget`` (6),
|
|
45
|
+
``--refresh-timeout`` (10) and ``--refresh-interval`` (60) are advanced
|
|
46
|
+
overrides in seconds. Both complete commands and guided selection use these
|
|
47
|
+
defaults without extra prompts. An unchanged or temporarily unavailable
|
|
48
|
+
subscription keeps the existing pool and bounded retry cadence. A recent
|
|
49
|
+
refresh can defer the next fetch; server Retry-After can defer it further.
|
|
50
|
+
These are not restoration-time guarantees.
|
|
51
|
+
|
|
52
|
+
Default selection evidence
|
|
53
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
54
|
+
|
|
55
|
+
A deterministic comparison used the real session scheduler/private provider
|
|
56
|
+
publication with injected network time: 1/5/10/20 nodes, five ordering seeds,
|
|
57
|
+
one working node, two-second fetches, and 1/3/5/8-second successful probes.
|
|
58
|
+
The reference replayed the recovery loop at ``7f40af8`` with its 300-second
|
|
59
|
+
refresh interval. Controller and process latency were not simulated; results
|
|
60
|
+
start at confirmed recovery, excluding failure detection.
|
|
61
|
+
|
|
62
|
+
For complete replacement with a one-second working node, the 3-second default
|
|
63
|
+
reduced sample P95 from 405 to 42 simulated seconds (maximum 54). For partial
|
|
64
|
+
failure with a three-second working node, sample P95 was 35 seconds, versus
|
|
65
|
+
223 with a two-second fast budget and 55 with a five-second fast budget.
|
|
66
|
+
Three seconds is the smallest compared budget that accepts this moderately
|
|
67
|
+
slow route on the first sweep. It is a workload choice, not a universal optimum.
|
|
68
|
+
For five-second working nodes the fast sweep adds work: sample P95 was 245
|
|
69
|
+
seconds versus 105 in the reference. Normal-budget retries preserve recovery
|
|
70
|
+
in this case; users of consistently slow routes can increase the fast budget.
|
|
71
|
+
|
|
72
|
+
``test/runtime/test_fast_recovery.py`` pins the default first-sweep bound for
|
|
73
|
+
1--20 nodes with 1/3-second successful probes over five seeds, prompt complete
|
|
74
|
+
replacement, independent refresh even at round exhaustion, throttling and
|
|
75
|
+
normal-budget fallback. These model checks supplement the real protocol
|
|
76
|
+
data-plane suite; they do not replace it or imply public-network percentiles.
|
|
77
|
+
|
|
78
|
+
Selection policies
|
|
79
|
+
------------------
|
|
80
|
+
|
|
81
|
+
* ``none`` stops after confirmed failure without restarting or refreshing.
|
|
82
|
+
* ``fixed`` retries only the initial node identity.
|
|
83
|
+
* ``random`` visits a shuffled pool without replacement before another sweep.
|
|
84
|
+
* ``adaptive`` uses session-local, aging success estimates and recovery-only
|
|
85
|
+
exploration; all eligible nodes must eventually receive an attempt.
|
|
86
|
+
* ``fallback`` composes the closed stages ``current``, ``adaptive`` and
|
|
87
|
+
``random``. The default is ``current:1,adaptive:3,random:all``. Stage names
|
|
88
|
+
must be unique; counts are positive bounded integers or ``all``. Current
|
|
89
|
+
permits only one attempt. Candidates are deduplicated across stages.
|
|
90
|
+
|
|
91
|
+
Retry timing uses capped exponential backoff with jitter, separate node
|
|
92
|
+
cooldowns and refresh throttling. A brief success does not reset escalation;
|
|
93
|
+
only a stable healthy period does. No tight loop is allowed for exhausted,
|
|
94
|
+
unchanged, disabled or cooling-down pools.
|
|
95
|
+
|
|
96
|
+
Execution and outputs
|
|
97
|
+
---------------------
|
|
98
|
+
|
|
99
|
+
The session keeps its home-wide lock, listener port and optional credentials
|
|
100
|
+
through degradation. Mihomo uses atomic private single-provider publication
|
|
101
|
+
and authenticated bounded reloads. Exact candidate acceptance, selection and
|
|
102
|
+
absence of direct bypass must be checked before connectivity can establish
|
|
103
|
+
readiness. Each control request has an absolute wall deadline covering response
|
|
104
|
+
headers and body, including slow trickles. A standard-library buffered reader
|
|
105
|
+
clamps each underlying socket read to the remaining time; no deadline worker
|
|
106
|
+
is allocated. Ambiguous control state, authentication, integrity, TLS, permission
|
|
107
|
+
and unsafe cleanup failures remain terminal. Health probes report certificate
|
|
108
|
+
validation failure and explicit HTTP 407 responses as closed terminal
|
|
109
|
+
verdicts, never as ordinary target outages. CONNECT 407 refusals are recognized
|
|
110
|
+
only through the pinned Requests/urllib3/standard-library exception chain and
|
|
111
|
+
the locally generated status prefix; arbitrary exception messages are never
|
|
112
|
+
searched or logged. Other proxy connection failures remain retryable. A real
|
|
113
|
+
loopback proxy refusal verifies classification across the health process
|
|
114
|
+
boundary. Confirmed child exit must not be confused with inability to stop a child.
|
|
115
|
+
|
|
116
|
+
Cache age requests a refresh but does not disqualify verified cached nodes.
|
|
117
|
+
Temporary refresh failure preserves the last good revision. Successful refresh
|
|
118
|
+
prunes removed identities and statistics; removing the fixed identity produces
|
|
119
|
+
an actionable error. Recovery refresh receives an independent budget and respects its
|
|
120
|
+
own minimum interval, backoff and server Retry-After. Retry-After is bounded
|
|
121
|
+
to one day; malformed values are discarded. Refresh starts no more often than
|
|
122
|
+
once per 60 seconds by default, doubles its delay after consecutive transport
|
|
123
|
+
failures up to one hour, and resets after success. Mandatory worker cleanup has
|
|
124
|
+
separate bounded stop intervals and must complete even after the network
|
|
125
|
+
budget expires; inability to prove cleanup is terminal. A standalone
|
|
126
|
+
subscription operation retains its original home lock while cleanup remains
|
|
127
|
+
unconfirmed. The same manager, used on its owning thread, may release that
|
|
128
|
+
retained lock on its next operation only after the supervisor confirms both worker termination and
|
|
129
|
+
artifact removal. A runtime session similarly refuses to announce stopped
|
|
130
|
+
or release its own lock while subscription cleanup is pending. No cleanup
|
|
131
|
+
thread releases a thread-owned FileLock or acquires a second home lock.
|
|
132
|
+
The subscription caller waits on a starter-owned completion event rather than
|
|
133
|
+
an interruptible thread join, which can incorrectly report a live starter as
|
|
134
|
+
stopped on older CPython versions. The cleanup supervisor also confirms actual
|
|
135
|
+
starter exit before removing the private worker directory.
|
|
136
|
+
Acquired operation locks remain strongly referenced until explicit exit, so
|
|
137
|
+
discarding a failed owner cannot release an unconfirmed operation through
|
|
138
|
+
garbage collection. Discarding such an owner forfeits in-process cleanup
|
|
139
|
+
recovery; the home stays locked until the process exits.
|
|
140
|
+
|
|
141
|
+
Sanitized events expose starting, degraded, retrying, ready and stopped states,
|
|
142
|
+
actual retry delays, skip reasons and current health. No event falsely reports
|
|
143
|
+
readiness or exposes secrets. Threads, children, statistics and recent logs
|
|
144
|
+
remain bounded for an indefinitely running session. Ctrl-C and SIGTERM must
|
|
145
|
+
cancel probes, refreshes and backoff and complete safe cleanup. The CLI owns
|
|
146
|
+
SIGINT and SIGTERM handlers only during the foreground session. The first
|
|
147
|
+
signal requests unwinding; repeated signals are ignored until cleanup has
|
|
148
|
+
finished, then prior handlers are restored. Successful cancellation exits
|
|
149
|
+
with 128 plus the signal number. Cleanup failure remains a terminal error.
|
|
150
|
+
|
|
151
|
+
Lifecycle events use a separate optional event callback. JSONL emits these
|
|
152
|
+
events on stdout and ordinary logs on stderr, independent of log-level
|
|
153
|
+
filtering. The session writes the same bounded event summary to its private
|
|
154
|
+
log. Each event includes a closed reason code, attempt and round counters,
|
|
155
|
+
candidate count, last healthy effective node, loaded node, attempted node,
|
|
156
|
+
current quorum and actual next delay. Startup emits ready only after access
|
|
157
|
+
publication; recovery emits ready only after acceptance and quorum. Stopped
|
|
158
|
+
is emitted only after child and artifact cleanup succeeds, while the home
|
|
159
|
+
lock still protects the event log write. Refresh events preserve the current
|
|
160
|
+
state and distinguish stale cache, unchanged content, updated content and
|
|
161
|
+
transient transport failure. Repeated stop is
|
|
162
|
+
idempotent. A closed output stream does not interrupt service.
|
|
163
|
+
|
|
164
|
+
Default network checks run in one disposable spawned process with at most
|
|
165
|
+
three request threads. The parent includes process startup in the check
|
|
166
|
+
budget, terminates the process on timeout or interruption, and confirms exit
|
|
167
|
+
before accepting another batch. Credentials travel through multiprocessing
|
|
168
|
+
IPC rather than command arguments or files. Results use a bounded, validated
|
|
169
|
+
JSON envelope with closed diagnostic codes. Cleanup retains a separate bounded
|
|
170
|
+
budget and fails closed on uncertain process ownership. Injected transports
|
|
171
|
+
run in-process for deterministic testing. Library scripts that launch default
|
|
172
|
+
probes must use the standard ``if __name__ == "__main__"`` entry guard
|
|
173
|
+
required by multiprocessing spawn; the CLI already provides that guard.
|
|
174
|
+
The installed ``self-check`` exercises the actual spawned health worker against
|
|
175
|
+
a temporary loopback HTTP server. It requires a successful round trip and
|
|
176
|
+
confirmed cleanup; standalone artifact CI runs this check on each target OS.
|
|
177
|
+
|
|
178
|
+
Injected in-process checks allocate at most three workers. If a request outlives
|
|
179
|
+
a check's budget, subsequent checks report it as unfinished and allocate no new
|
|
180
|
+
workers until that batch finishes. Late results do not establish readiness for
|
|
181
|
+
a later check. Cancellation prevents pending targets from starting. Completion
|
|
182
|
+
is tracked with worker-owned events instead of interruptible joins; cleanup
|
|
183
|
+
must confirm all workers have exited before releasing the home lock. An
|
|
184
|
+
unconfirmed worker makes cleanup fail closed. This bounds worker accumulation but does not by itself prove
|
|
185
|
+
that an arbitrary injected transport can be cancelled. Default network
|
|
186
|
+
transports instead use the disposable process described above. Native platform
|
|
187
|
+
and packaged-executable verification run in the repository CI matrix.
|
|
188
|
+
|
|
189
|
+
Runtime logs retain recent diagnostics within a 4 MiB file. Both producers
|
|
190
|
+
serialize writes under the existing shared lock. Descriptors use binary mode
|
|
191
|
+
on Windows so byte bounds and compaction offsets are not changed by newline
|
|
192
|
+
translation. On overflow they discard
|
|
193
|
+
the oldest portion, retain complete recent lines from the final half and
|
|
194
|
+
append the new redacted line through the same validated descriptor. No
|
|
195
|
+
rotation paths are created. A crash during this in-place compaction can lose
|
|
196
|
+
diagnostic history; it cannot modify managed configuration or credentials.
|
|
197
|
+
|
|
198
|
+
Verification required before merge
|
|
199
|
+
----------------------------------
|
|
200
|
+
|
|
201
|
+
Tests are written before behavior. Deterministic scenarios cover startup
|
|
202
|
+
offline then online, outages longer than 120 seconds, all nodes unavailable,
|
|
203
|
+
one working alternate, subscription scope, fixed identity, no healthy
|
|
204
|
+
switching, hundreds of candidates, cooldowns, unchanged and failing refresh,
|
|
205
|
+
old usable cache, removed fixed identity, flapping and cancellation at each
|
|
206
|
+
blocking boundary. Adversarial reload tests cover empty and malicious
|
|
207
|
+
providers, stale accepted content, authorization and rollback failures.
|
|
208
|
+
|
|
209
|
+
Real qualified-backend data-plane tests cover every allowed protocol and
|
|
210
|
+
container, including hot switches with stable listener and credentials.
|
|
211
|
+
Long-run tests verify bounded workers, logs and statistics. Existing secret
|
|
212
|
+
matrices must include new output channels. Explicit and guided CLI behavior
|
|
213
|
+
must agree; rendered help is checked at 72, 80, 100 and 120 columns.
|
|
214
|
+
|
|
215
|
+
All changed or affected functions require 100 percent branch coverage,
|
|
216
|
+
including native platform evidence when necessary, without exclusion pragmas
|
|
217
|
+
or a whole-repository average substituting for the affected-area audit.
|
|
218
|
+
Python 3.7 compatibility, normal test gates, generated API documentation,
|
|
219
|
+
documentation build and package build must pass. The PR body is English;
|
|
220
|
+
completion requires review and CI evidence that the full scope is merge-ready.
|