-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add Host Functions support #13
Conversation
I will need to do some tests regarding memory leaks, since FFI callbacks seem to leak by default:
|
$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; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mhmd-azeez -- this is pretty neat! the ability to auto-cast (?) these types, e.g. (string $key, string $value)
in the signature is impressive. Maybe it's just my lack of familiarity with PHP, but I think it would be really helpful to have some notes/docs on this in the source for this callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I added parameter details to the README, not sure if that's what you meant. let me know if you think we need more info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those work great - thank you!
return $p->write_block($value); | ||
}); | ||
|
||
$kvWrite = new HostFunction("kv_write", [ExtismValType::I64, ExtismValType::I64], [], function (CurrentPlugin $p, int $keyPtr, int $valuePtr) use (&$kvstore) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(related to the previous comment)
I suppose the docs I'm looking for are primarily about how the transformation of the "higher level" types into these works. And, what are the limits? If my string
for example, is actually bytes, is there any issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK there is no byte[]
type in php, and string
is used in its place in the standard library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The dynamic typing is great! And the host function bindings look good too - I read through several times and didn't see any issues.
I think this is ready to merge once you figure out if you need to release the callback memory.
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: php-sdk-memory-test.mp4As for freeing memory,
-- PHP Docs We are only using managed data, so we should be fine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent! Thank you
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.