Closed mhmd-azeez closed 9 months ago
cc @AtlantisPleb
I will need to do some tests regarding memory leaks, since FFI callbacks seem to leak by default: https://www.php.net/manual/en/ffi.examples-callback.php
Although this works, this functionality is not supported on all libffi platforms, is not efficient and leaks resources by the end of request. It is therefore recommended to minimize the usage of PHP callbacks.
After a lot of experimenting, it seems like host functions leak memory, which is expected because it's a documented behavior of FFI + callbacks. So, I have decided to mark it as experimental for now, until we can find ways around this or maybe we get more user feedback.
However, the good news is, http servers like Apache are already designed to handle such scenarios fairly well, for example, let's consider this test:
for ($i = 0; $i < 10; $i++) {
$kvstore = [];
$kvRead = new HostFunction("kv_read", [ExtismValType::I64], [ExtismValType::I64], function (CurrentPlugin $p, string $key) use (&$kvstore) {
return $kvstore[$key] ?? "\0\0\0\0";
});
$kvWrite = new HostFunction("kv_write", [ExtismValType::I64, ExtismValType::I64], [], function (string $key, string $value) use (&$kvstore) {
$kvstore[$key] = $value;
});
$plugin = new Plugin($manifest, true, [$kvRead, $kvWrite]);
$output = $plugin->call("count_vowels", "Hello World!");
if ($i % 1 === 0) {
echo "Iteration: $i => " . $lib->count . PHP_EOL;
}
}
This is how Apache behaves under test:
https://github.com/extism/php-sdk/assets/16880059/7af966b1-7eb3-42d4-885e-c0b7a348713d
As for freeing memory,
Managed data lives together with the returned FFI\CData object, and is released when the last reference to that object is released by regular PHP reference counting or GC. Unmanaged data should be released by calling FFI::free(), when no longer needed.
-- PHP Docs
We are only using managed data, so we should be fine.
Fixes #11
User Data. Wasn't able to find a way to pin PHP objects and get their address. Users can use captured variables in the callback closures instead.