Skip to content

Commit

Permalink
fix: python host leaking wasmtime memory
Browse files Browse the repository at this point in the history
  • Loading branch information
TheEdward162 committed Oct 11, 2023
1 parent aff210a commit 3903847
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/python_host/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies = [
"charset-normalizer ~= 3.1.0",
"idna ~= 3.4",
"urllib3 ~= 2.0.3",
"wasmtime ~= 10.0.0"
"wasmtime ~= 13.0.0"
]

[project.urls]
Expand Down
8 changes: 5 additions & 3 deletions packages/python_host/src/one_sdk/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import platform
import sys

from typing import Any, BinaryIO, Callable, List, Mapping, Optional, cast
from typing import Any, BinaryIO, Callable, List, Mapping, Optional, cast, Union

import struct
from types import SimpleNamespace
from dataclasses import dataclass
import functools
import weakref

from wasmtime import Engine, Instance, Memory, Store, Module, Linker, WasiConfig
import wasmtime
Expand Down Expand Up @@ -68,7 +69,7 @@ class _PerformState:
security: SecurityValuesMap
result: Optional[Any] = None
error: Optional[PerformError] = None
exception: Optional[UnexpectedError] = None
exception: Union[None, UnexpectedError, ValidationError] = None

def __init__(
self,
Expand All @@ -82,7 +83,7 @@ def __init__(

# linked modules and state
self._linker.define_wasi()
sf_host_link(self._linker, self)
sf_host_link(self._linker, weakref.ref(self))

wasi = WasiConfig()
wasi.inherit_stdout()
Expand Down Expand Up @@ -358,6 +359,7 @@ def _create_developer_dump(self, core: "WasiApp._AppCore"):
if len(events) > 0:
self._persistence.persist_developer_dump(events)

@staticmethod
def user_agent():
sys_platform = platform.system()
sys_arch = platform.architecture()[0]
Expand Down
20 changes: 19 additions & 1 deletion packages/python_host/src/one_sdk/sf_host.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import TYPE_CHECKING, Tuple
from weakref import ReferenceType
if TYPE_CHECKING:
from one_sdk.app import WasiApp

Expand Down Expand Up @@ -39,10 +40,19 @@ def _abi_ok(value: int) -> AbiResult:
def _abi_err(value: int) -> AbiResult:
return _join_abi_result(int(value), 1)

def link(linker: Linker, app: "WasiApp"):
def _get_app(app_ref: ReferenceType["WasiApp"]) -> "WasiApp":
app = app_ref()
if app is None:
raise RuntimeError("WasiApp already destroyed")

return app

def link(linker: Linker, app_ref: ReferenceType["WasiApp"]):
message_store: HandleMap[bytes] = HandleMap()

def __export_message_exchange(msg_ptr: Ptr, msg_len: Size, out_ptr: Ptr, out_len: Size, ret_handle: Ptr) -> Size:
app = _get_app(app_ref)

memory = app.memory
message = json.loads(
memory.read_bytes(msg_ptr, msg_len).decode("utf-8")
Expand All @@ -59,6 +69,8 @@ def __export_message_exchange(msg_ptr: Ptr, msg_len: Size, out_ptr: Ptr, out_len
return _abi_ok(len(response_bytes))

def __export_message_exchange_retrieve(handle: int, out_ptr: Ptr, out_len: Size) -> AbiResult:
app = _get_app(app_ref)

response_bytes = message_store.remove(handle)
if response_bytes is None:
return _abi_err(WasiErrno.EBADF)
Expand All @@ -69,6 +81,8 @@ def __export_message_exchange_retrieve(handle: int, out_ptr: Ptr, out_len: Size)
return _abi_ok(count)

def __export_stream_read(handle: int, out_ptr: Ptr, out_len: Size) -> AbiResult:
app = _get_app(app_ref)

try:
read_count = app.memory.write_bytes(out_ptr, out_len, app.stream_read(handle, out_len))
except WasiError as e:
Expand All @@ -77,6 +91,8 @@ def __export_stream_read(handle: int, out_ptr: Ptr, out_len: Size) -> AbiResult:
return _abi_ok(read_count)

def __export_stream_write(handle: int, in_ptr: Ptr, in_len: Size) -> AbiResult:
app = _get_app(app_ref)

try:
write_count = app.stream_write(handle, app.memory.read_bytes(in_ptr, in_len))
except WasiError as e:
Expand All @@ -85,6 +101,8 @@ def __export_stream_write(handle: int, in_ptr: Ptr, in_len: Size) -> AbiResult:
return _abi_ok(write_count)

def __export_stream_close(handle: int) -> AbiResult:
app = _get_app(app_ref)

try:
app.stream_close(handle)
except WasiError as e:
Expand Down

0 comments on commit 3903847

Please sign in to comment.