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
2 changes: 1 addition & 1 deletion .github/workflows/servc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:

env:
SERVC_VERSION: 0.5.0
SERVC_VERSION: 0.5.1

permissions:
contents: write
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
pip install -r requirements-dev.txt

- name: Type check
run: mypy servc
run: mypy servc --check-untyped-defs

- name: Run tests
env:
Expand Down
92 changes: 50 additions & 42 deletions servc/svc/com/worker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
from typing import Any, List
from typing import Any, List, Tuple

from servc.svc import ComponentType, Middleware
from servc.svc.com.bus import BusComponent, OnConsuming
from servc.svc.com.cache import CacheComponent
from servc.svc.com.worker.hooks import evaluate_post_hooks, evaluate_pre_hooks
from servc.svc.com.worker.types import RESOLVER_CONTEXT, RESOLVER_MAPPING
from servc.svc.com.worker.types import RESOLVER, RESOLVER_CONTEXT, RESOLVER_MAPPING
from servc.svc.config import Config
from servc.svc.io.input import InputType
from servc.svc.io.output import (
InvalidInputsException,
MethodNotFoundException,
NoProcessingException,
NotAuthorizedException,
ResponseArtifact,
StatusCode,
)
from servc.svc.io.response import getAnswerArtifact, getErrorArtifact
Expand Down Expand Up @@ -102,6 +103,35 @@ def connect(self):
bindEventExchange=self._bindToEventExchange,
)

def run_resolver(
self, method: RESOLVER, context: RESOLVER_CONTEXT, args: Tuple[str, Any]
) -> Tuple[StatusCode, ResponseArtifact | None]:
id, payload = args
try:
response = method(id, payload, context)
return StatusCode.OK, getAnswerArtifact(id, response)
except NotAuthorizedException as e:
return StatusCode.NOT_AUTHORIZED, getErrorArtifact(
id, str(e), StatusCode.NOT_AUTHORIZED
)
except InvalidInputsException as e:
return StatusCode.INVALID_INPUTS, getErrorArtifact(
id, str(e), StatusCode.INVALID_INPUTS
)
except NoProcessingException:
return StatusCode.NO_PROCESSING, None
except MethodNotFoundException as e:
return StatusCode.METHOD_NOT_FOUND, getErrorArtifact(
id, str(e), StatusCode.METHOD_NOT_FOUND
)
except Exception as e:
if self._config.get(f"conf.{self.name}.exiton5xx"):
print("Exiting due to 5xx error", e, flush=True)
exit(1)
return StatusCode.SERVER_ERROR, getErrorArtifact(
id, str(e), StatusCode.SERVER_ERROR
)

def inputProcessor(self, message: Any) -> StatusCode:
bus = self._busClass(
self._config.get(f"conf.{self._bus.name}"),
Expand All @@ -126,8 +156,14 @@ def inputProcessor(self, message: Any) -> StatusCode:
return StatusCode.INVALID_INPUTS
if message["event"] not in self._eventResolvers:
return StatusCode.METHOD_NOT_FOUND
self._eventResolvers[message["event"]]("", {**message}, context)
return StatusCode.OK

status_code, response = self.run_resolver(
self._eventResolvers[message["event"]],
context,
("", {**message}),
)

return status_code

if message["type"] in [InputType.INPUT.value, InputType.INPUT]:
if "id" not in message:
Expand Down Expand Up @@ -177,45 +213,17 @@ def inputProcessor(self, message: Any) -> StatusCode:
if not continueExecution:
return StatusCode.OK

statusCode: StatusCode = StatusCode.OK
try:
response = self._resolvers[artifact["method"]](
message["id"],
artifact["inputs"],
context,
)
cache.setKey(message["id"], getAnswerArtifact(message["id"], response))
except NotAuthorizedException as e:
cache.setKey(
message["id"],
getErrorArtifact(message["id"], str(e), StatusCode.NOT_AUTHORIZED),
)
statusCode = StatusCode.NOT_AUTHORIZED
except InvalidInputsException as e:
cache.setKey(
message["id"],
getErrorArtifact(message["id"], str(e), StatusCode.INVALID_INPUTS),
)
statusCode = StatusCode.INVALID_INPUTS
except NoProcessingException:
statusCode, response = self.run_resolver(
self._resolvers[artifact["method"]],
context,
(message["id"], artifact["inputs"]),
)
if statusCode == StatusCode.NO_PROCESSING:
return StatusCode.NO_PROCESSING
except MethodNotFoundException as e:
cache.setKey(
message["id"],
getErrorArtifact(
message["id"], str(e), StatusCode.METHOD_NOT_FOUND
),
)
statusCode = StatusCode.METHOD_NOT_FOUND
except Exception as e:
cache.setKey(
message["id"],
getErrorArtifact(message["id"], str(e), StatusCode.SERVER_ERROR),
)
statusCode = StatusCode.SERVER_ERROR
finally:
evaluate_post_hooks(bus, cache, message, artifact)
return statusCode

cache.setKey(message["id"], response)
evaluate_post_hooks(bus, cache, message, artifact)
return statusCode

cache.setKey(
message["id"],
Expand Down
9 changes: 8 additions & 1 deletion servc/svc/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
"conf.bus.routemap": json.loads(os.getenv("CONF__BUS__ROUTEMAP", json.dumps({}))),
"conf.bus.prefix": "",
"conf.worker.bindtoeventexchange": True,
"conf.worker.exiton5xx": True,
}

BOOLEAN_CONFIGS = os.getenv(
"SERVC_BOOLEAN_CONFIGS", "conf.worker.exiton5xx,conf.worker.bindtoeventexchange"
).split(",")
DOT_MARKER = os.getenv("SERVC_DOT_MARKER", "_DOT_")
DASH_MARKER = os.getenv("SERVC_DASH_MARKER", "_DASH_")

Expand Down Expand Up @@ -53,7 +57,10 @@ def __init__(self, config_path: str | None = None):
"CONF__FILE",
"CONF__BUS__ROUTEMAP",
):
self.setValue(key.replace(DASH_MARKER, "-").replace("__", "."), value)
newkey = key.replace(DASH_MARKER, "-").replace("__", ".")
if newkey.lower() in BOOLEAN_CONFIGS:
value = value.lower() in ("yes", "true", "t", "1")
self.setValue(newkey, value)

self.setValue("conf.bus.instanceid", self.get("conf.instanceid"))

Expand Down