Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.1] - 2026-04-05

### Fixed
- **3 bugs found by live broker testing:**
- `cache keys`: sync/async mismatch — `cacher.keys()` is sync
- `destroy`: use `registry.__services__` fallback (broker has no `destroyService` yet)
- `load`: use `broker.register()` (broker has no `addLocalService`)

## [0.3.0] - 2026-04-05

### Added
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "moleculerpy-repl"
version = "0.3.0"
version = "0.3.1"
description = "Interactive CLI shell for MoleculerPy microservices framework"
readme = "README.md"
license = "MIT"
Expand Down
5 changes: 4 additions & 1 deletion src/moleculerpy_repl/commands/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ async def _list_keys(self, cacher: Any, args: ParsedArgs) -> CommandResult:

try:
if hasattr(cacher, "keys"):
keys = await cacher.keys(pattern) if pattern else await cacher.keys()
raw_keys = cacher.keys(pattern) if pattern else cacher.keys()
# keys() may be sync or async depending on cacher impl
import asyncio
keys = (await raw_keys) if asyncio.iscoroutine(raw_keys) else raw_keys
else:
return CommandResult(
success=False,
Expand Down
32 changes: 19 additions & 13 deletions src/moleculerpy_repl/commands/destroy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,40 @@ async def execute(self, broker: Any, args: ParsedArgs) -> CommandResult:
service_name = args.positional[0]

try:
# Try broker.destroyService first (Node.js pattern)
if hasattr(broker, "destroyService"):
# Find the service instance by name
service = None
if hasattr(broker, "services"):
service = broker.services.get(service_name)

if service is None and hasattr(broker, "registry"):
service = broker.registry.__services__.get(service_name)
if service is None:
return CommandResult(success=False, error=f"Service '{service_name}' not found")

await broker.destroyService(service)
return CommandResult(
success=True,
output=f"Service '{service_name}' destroyed.",
)
elif hasattr(broker, "registry"):
# Fallback: remove from registry directly
registry = broker.registry
if service_name not in registry.__services__:
return CommandResult(success=False, error=f"Service '{service_name}' not found")
del registry.__services__[service_name]
# Remove associated actions
registry.__actions__ = [a for a in registry.__actions__ if not a.name.startswith(f"{service_name}.")]
registry._actions_by_name = {
k: v for k, v in registry._actions_by_name.items()
if not k.startswith(f"{service_name}.")
}
else:
return CommandResult(
success=False,
error="broker.destroyService is not supported in this version",
)
return CommandResult(success=False, error="Cannot destroy: no registry access")

return CommandResult(success=True, output=f"Service '{service_name}' destroyed.")
except Exception as e:
return CommandResult(success=False, error=f"Destroy failed: {e}")

def get_completions(self, broker: Any, text: str, line: str) -> list[str]:
"""Get service name completions."""
try:
if hasattr(broker, "services"):
return [name for name in broker.services if name.startswith(text)]
if hasattr(broker, "registry"):
return [n for n in broker.registry.__services__ if n.startswith(text)]
except Exception:
pass
return []
10 changes: 8 additions & 2 deletions src/moleculerpy_repl/commands/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,14 @@ async def execute(self, broker: Any, args: ParsedArgs) -> CommandResult:
error=f"No Service subclass found in {file_path.name}",
)

svc = service_class(broker)
await broker.addLocalService(svc)
svc = service_class()
# Use broker.register() — the standard MoleculerPy API
if hasattr(broker, "register"):
await broker.register(svc)
elif hasattr(broker, "addLocalService"):
await broker.addLocalService(svc)
else:
return CommandResult(success=False, error="Cannot register service: no register method")

return CommandResult(
success=True,
Expand Down
Loading