feat(wasmguest): wire bnwasm Pool into guest CoreServices (WO-WZ-004)
Bind the db.* driver over the same transport as the capability stubs so deps.Pool keeps working for plugin sqlc code: - dispatch.go: g.services.Pool = bnwasm.NewPool(capTransport) (nil on native/DESCRIBE → fails cleanly, matching the caps stubs). - hostcalls.go (wasip1): also bind the "bnwasm" database/sql driver's process-global transport to CallHost. - docs/wasm-abi.md: document the implemented guest driver + pgx-primary rationale under the Pool disposition. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7881aeee05
commit
081bacf2ab
@ -209,7 +209,18 @@ zero value / best-effort on transport failure.
|
|||||||
the per-plugin Postgres role. `DbError.code` carries the SQLSTATE.
|
the per-plugin Postgres role. `DbError.code` carries the SQLSTATE.
|
||||||
Transactions: `tx_begin` returns an opaque `tx_handle` (never 0); `query`/
|
Transactions: `tx_begin` returns an opaque `tx_handle` (never 0); `query`/
|
||||||
`exec` with `tx_handle = 0` run autocommit. Handles die with the call
|
`exec` with `tx_handle = 0` run autocommit. Handles die with the call
|
||||||
chain's deadline so a guest can never pin a connection.
|
chain's deadline so a guest can never pin a connection. **Guest side
|
||||||
|
(WO-WZ-004):** `core/plugin/wasmguest/bnwasm` implements this over the
|
||||||
|
transport as two surfaces — a `database/sql` driver registered as `"bnwasm"`,
|
||||||
|
and a `plugin.Pool` handing out a `pgx.Tx`-shaped value. The latter is the
|
||||||
|
primary path: current plugins' sqlc configs use `sql_package: "pgx/v5"`, so
|
||||||
|
their generated `DBTX` needs `pgconn.CommandTag`/`pgx.Rows`/`pgx.Row` (which
|
||||||
|
`database/sql` cannot produce), and the `Pool`/`Tx` satisfy it with no source
|
||||||
|
edits. `DbError` surfaces as `*pgconn.PgError` (SQLSTATE preserved for
|
||||||
|
`errors.As`). Named args (`pgx.NamedArgs`/`QueryRewriter`) and nested
|
||||||
|
transactions/savepoints are rejected with clear errors — no fleet plugin uses
|
||||||
|
either. The DbValue↔Go scan mapping is pinned in the exported
|
||||||
|
`bnwasm.DbValueFixtures` table, which the WO-WZ-007 host executor mirrors.
|
||||||
- `Interceptors` (`connect.Option`) → host-side only; RBAC merges from
|
- `Interceptors` (`connect.Option`) → host-side only; RBAC merges from
|
||||||
`manifest.rbac_method_roles`.
|
`manifest.rbac_method_roles`.
|
||||||
- `AppURL` / `MediaPath` → delivered once in `LoadRequest.host_config`.
|
- `AppURL` / `MediaPath` → delivered once in `LoadRequest.host_config`.
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
abiv1 "git.dev.alexdunmow.com/block/core/abi/v1"
|
abiv1 "git.dev.alexdunmow.com/block/core/abi/v1"
|
||||||
"git.dev.alexdunmow.com/block/core/plugin"
|
"git.dev.alexdunmow.com/block/core/plugin"
|
||||||
|
"git.dev.alexdunmow.com/block/core/plugin/wasmguest/bnwasm"
|
||||||
"git.dev.alexdunmow.com/block/core/plugin/wasmguest/caps"
|
"git.dev.alexdunmow.com/block/core/plugin/wasmguest/caps"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
@ -68,6 +69,11 @@ func newGuest(reg plugin.PluginRegistration) *guest {
|
|||||||
templates: newCaptureTemplateRegistry(),
|
templates: newCaptureTemplateRegistry(),
|
||||||
}
|
}
|
||||||
g.services = caps.NewCoreServices(capTransport)
|
g.services = caps.NewCoreServices(capTransport)
|
||||||
|
// Pool is left zero by NewCoreServices (it does not cross as a capability
|
||||||
|
// call); bind the db.* driver over the same transport so deps.Pool keeps
|
||||||
|
// working for plugin sqlc code. A nil transport (native/DESCRIBE) yields a
|
||||||
|
// Pool whose calls fail cleanly, matching the capability stubs.
|
||||||
|
g.services.Pool = bnwasm.NewPool(bnwasm.Transport(capTransport))
|
||||||
g.rag, _ = g.services.RAGService.(*caps.RAGStub)
|
g.rag, _ = g.services.RAGService.(*caps.RAGStub)
|
||||||
g.registerErr = runRegister(reg, g.templates, g.blocks)
|
g.registerErr = runRegister(reg, g.templates, g.blocks)
|
||||||
return g
|
return g
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
abiv1 "git.dev.alexdunmow.com/block/core/abi/v1"
|
abiv1 "git.dev.alexdunmow.com/block/core/abi/v1"
|
||||||
|
"git.dev.alexdunmow.com/block/core/plugin/wasmguest/bnwasm"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,8 +29,13 @@ func hostCall(ptr uint32, size uint32) uint64
|
|||||||
|
|
||||||
// init binds the capability-stub transport (package caps) to the real
|
// init binds the capability-stub transport (package caps) to the real
|
||||||
// host_call-backed CallHost. Only wasip1 has a host to call; native builds
|
// host_call-backed CallHost. Only wasip1 has a host to call; native builds
|
||||||
// leave caps' transport nil, so their capability calls fail cleanly.
|
// leave caps' transport nil, so their capability calls fail cleanly. The same
|
||||||
func init() { capTransport = CallHost }
|
// transport backs the "bnwasm" database/sql driver for plugins that open a
|
||||||
|
// *sql.DB (the pgx-flavored plugin.Pool path binds capTransport in dispatch).
|
||||||
|
func init() {
|
||||||
|
capTransport = CallHost
|
||||||
|
bnwasm.SetDefaultTransport(bnwasm.Transport(CallHost))
|
||||||
|
}
|
||||||
|
|
||||||
// HostError is a failed capability call's AbiError surfaced as a Go error.
|
// HostError is a failed capability call's AbiError surfaced as a Go error.
|
||||||
type HostError struct {
|
type HostError struct {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user