Skip to content

Commit

Permalink
feat: index Environment.packages by namespace and short name
Browse files Browse the repository at this point in the history
Closes: #123
  • Loading branch information
MHajoha committed Nov 8, 2024
1 parent 1217fb3 commit 35319a7
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description = "QuestionPy application server"
authors = ["Technische Universität Berlin, innoCampus <[email protected]>"]
license = "MIT"
homepage = "https://questionpy.org"
version = "0.3.1"
version = "0.4.0"
packages = [
{ include = "questionpy_common" },
{ include = "questionpy_server" }
Expand Down
19 changes: 14 additions & 5 deletions questionpy_common/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from contextvars import ContextVar
from dataclasses import dataclass
from importlib.resources.abc import Traversable
from typing import Protocol, TypeAlias
from typing import NamedTuple, Protocol, TypeAlias

from questionpy_common.api.package import QPyPackageInterface
from questionpy_common.api.qtype import QuestionTypeInterface
Expand All @@ -18,6 +18,7 @@
"OnRequestCallback",
"Package",
"PackageInitFunction",
"PackageNamespaceAndShortName",
"RequestUser",
"WorkerResourceLimits",
"get_qpy_environment",
Expand All @@ -42,10 +43,8 @@ class WorkerResourceLimits:

class Package(Protocol):
@property
@abstractmethod
def manifest(self) -> Manifest: ...

@abstractmethod
def get_path(self, path: str) -> Traversable:
"""Gets a [Traversable][] object which allows reading files from the package.
Expand All @@ -59,6 +58,13 @@ def get_path(self, path: str) -> Traversable:
OnRequestCallback: TypeAlias = Callable[[RequestUser], None]


class PackageNamespaceAndShortName(NamedTuple):
"""Tuple of namespace and short name, identifying any version of a specific package."""

namespace: str
short_name: str


class Environment(Protocol):
type: str
"""The kind of worker we are running in.
Expand All @@ -81,8 +87,11 @@ class Environment(Protocol):
"""
main_package: Package
"""The main package whose entrypoint was called."""
packages: Mapping[str, Package]
"""All packages loaded in the worker, including the main package."""
packages: Mapping[PackageNamespaceAndShortName, Package]
"""All packages loaded in the worker, including the main package.
Keys are the package namespace and short name. Only one version of a package can be loaded at a time.
"""

@abstractmethod
def register_on_request_callback(self, callback: OnRequestCallback) -> None:
Expand Down
3 changes: 1 addition & 2 deletions questionpy_server/worker/impl/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,7 @@ async def stop(self, timeout: float) -> None:
log.info("Worker was killed because it did not stop gracefully")

async def get_manifest(self) -> ComparableManifest:
msg = GetQPyPackageManifest(path=str(self.package))
ret = await self.send_and_wait_for_response(msg, GetQPyPackageManifest.Response)
ret = await self.send_and_wait_for_response(GetQPyPackageManifest(), GetQPyPackageManifest.Response)
return ComparableManifest(**ret.manifest.model_dump())

async def get_options_form(
Expand Down
21 changes: 14 additions & 7 deletions questionpy_server/worker/runtime/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from questionpy_common.environment import (
Environment,
OnRequestCallback,
PackageNamespaceAndShortName,
RequestUser,
WorkerResourceLimits,
get_qpy_environment,
Expand Down Expand Up @@ -41,7 +42,7 @@
class EnvironmentImpl(Environment):
type: str
main_package: ImportablePackage
packages: dict[str, ImportablePackage]
packages: dict[PackageNamespaceAndShortName, ImportablePackage]
_on_request_callbacks: list[OnRequestCallback]
request_user: RequestUser | None = None
limits: WorkerResourceLimits | None = None
Expand All @@ -59,7 +60,7 @@ def __init__(self, server_connection: WorkerToServerConnection):
self._connection: WorkerToServerConnection = server_connection

self._worker_type: str | None = None
self._loaded_packages: dict[str, ImportablePackage] = {}
self._loaded_packages: dict[PackageNamespaceAndShortName, ImportablePackage] = {}

self._limits: WorkerResourceLimits | None = None

Expand Down Expand Up @@ -127,15 +128,15 @@ def on_msg_load_qpy_package(self, msg: LoadQPyPackage) -> MessageToServer:
if msg.main:
self._question_type = cast(QuestionTypeInterface, package_interface)

self._loaded_packages[str(msg.location)] = package
nssn = PackageNamespaceAndShortName(package.manifest.namespace, package.manifest.short_name)
self._loaded_packages[nssn] = package
return LoadQPyPackage.Response()

def on_msg_get_qpy_package_manifest(self, msg: GetQPyPackageManifest) -> MessageToServer:
if not self._worker_type:
self._raise_not_initialized(msg)
if not self._env:
self._raise_no_main_package_loaded(msg)

package = self._loaded_packages[msg.path]
return GetQPyPackageManifest.Response(manifest=package.manifest)
return GetQPyPackageManifest.Response(manifest=self._env.main_package.manifest)

def on_msg_get_options_form_definition(self, msg: GetOptionsForm) -> MessageToServer:
if not self._worker_type:
Expand Down Expand Up @@ -231,3 +232,9 @@ class WorkerNotInitializedError(Exception):

class MainPackageNotLoadedError(Exception):
pass


class PackageNotLoadedError(Exception):
def __init__(self, nssn: PackageNamespaceAndShortName) -> None:
super().__init__(f"No package '{nssn}' is loaded by this worker.")
self.nssn = nssn
1 change: 0 additions & 1 deletion questionpy_server/worker/runtime/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ class GetQPyPackageManifest(MessageToWorker):
"""Get the manifest data of the main package, which must previously have been loaded."""

message_id: ClassVar[MessageIds] = MessageIds.GET_QPY_PACKAGE_MANIFEST
path: str

class Response(MessageToServer):
"""Execute a QuestionPy package."""
Expand Down

0 comments on commit 35319a7

Please sign in to comment.