first commit
This commit is contained in:
141
example/main.go
Normal file
141
example/main.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"git.fsdpf.net/go/gobridge"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Score float64 `json:"score"`
|
||||
Level string `json:"level,omitempty"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
_, file, _, _ := runtime.Caller(0)
|
||||
script := filepath.Join(filepath.Dir(file), "worker.py")
|
||||
|
||||
pool, err := gobridge.NewPool(script,
|
||||
gobridge.WithWorkers(2),
|
||||
gobridge.WithMaxConns(4),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// ── 普通调用 ──────────────────────────────────────────────────────────
|
||||
sum, err := gobridge.Invoke[int](ctx, pool, "add", 3, 4)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("add(3, 4) =", sum) // 7
|
||||
|
||||
// ── 流式输出:Python yield → Go channel ──────────────────────────────
|
||||
ch, err := gobridge.Invoke[chan int](ctx, pool, "range_gen", 1, 6)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print("range_gen(1, 6) =")
|
||||
for v := range ch {
|
||||
fmt.Print(" ", v)
|
||||
}
|
||||
fmt.Println() // 1 2 3 4 5
|
||||
|
||||
// ── 流式输入:Go channel → Python Iterator ───────────────────────────
|
||||
inputCh := make(chan int, 10)
|
||||
go func() {
|
||||
for i := 1; i <= 5; i++ {
|
||||
inputCh <- i
|
||||
}
|
||||
close(inputCh)
|
||||
}()
|
||||
total, err := gobridge.Invoke[int](ctx, pool, "sum_stream", inputCh)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("sum_stream(1..5) =", total) // 15
|
||||
|
||||
// ── 双向流:Go channel 输入 + Go channel 输出 ────────────────────────
|
||||
inputCh2 := make(chan int, 10)
|
||||
go func() {
|
||||
for i := 1; i <= 5; i++ {
|
||||
inputCh2 <- i
|
||||
}
|
||||
close(inputCh2)
|
||||
}()
|
||||
outCh, err := gobridge.Invoke[chan int](ctx, pool, "double_stream", inputCh2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print("double_stream(1..5) =")
|
||||
for v := range outCh {
|
||||
fmt.Print(" ", v)
|
||||
}
|
||||
fmt.Println() // 1 4 9 16 25
|
||||
|
||||
// ── struct 普通调用 ───────────────────────────────────────────────────
|
||||
user, err := gobridge.Invoke[User](ctx, pool, "get_user", 42)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("get_user(42) = %+v\n", user)
|
||||
|
||||
// ── slice 输入,返回标量 ───────────────────────────────────────────────
|
||||
users := []User{
|
||||
{ID: 1, Name: "alice", Score: 5.0},
|
||||
{ID: 2, Name: "bob", Score: 8.0},
|
||||
{ID: 3, Name: "carol", Score: 12.0},
|
||||
}
|
||||
scoreSum, err := gobridge.Invoke[float64](ctx, pool, "total_score", users)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("total_score([alice,bob,carol]) = %.1f\n", scoreSum)
|
||||
|
||||
// ── slice 输入输出 ─────────────────────────────────────────────────────
|
||||
enriched, err := gobridge.Invoke[[]User](ctx, pool, "enrich_users", users)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("enrich_users:")
|
||||
for _, u := range enriched {
|
||||
fmt.Printf(" %+v\n", u)
|
||||
}
|
||||
|
||||
// ── 流式输出 struct:Python yield User → Go chan User ─────────────────
|
||||
userCh, err := gobridge.Invoke[chan User](ctx, pool, "gen_users", 3)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Print("gen_users(3) =")
|
||||
for u := range userCh {
|
||||
fmt.Printf(" {%d %s %.0f}", u.ID, u.Name, u.Score)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// ── 双向流 struct:Go chan User 输入 → Python 处理 → Go chan User 输出 ─
|
||||
inCh := make(chan User, 5)
|
||||
go func() {
|
||||
for _, u := range users {
|
||||
inCh <- u
|
||||
}
|
||||
close(inCh)
|
||||
}()
|
||||
procCh, err := gobridge.Invoke[chan User](ctx, pool, "process_users", inCh)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("process_users:")
|
||||
for u := range procCh {
|
||||
fmt.Printf(" %+v\n", u)
|
||||
}
|
||||
}
|
||||
75
example/worker.py
Normal file
75
example/worker.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "python"))
|
||||
|
||||
from gobridge import gobridge, run
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
@gobridge
|
||||
def add(a: int, b: int) -> int:
|
||||
return a + b
|
||||
|
||||
|
||||
@gobridge
|
||||
def range_gen(start: int, stop: int) -> Iterator[int]:
|
||||
"""流式输出:对应 Go 侧 Invoke[chan int]"""
|
||||
for i in range(start, stop):
|
||||
yield i
|
||||
|
||||
|
||||
@gobridge
|
||||
def sum_stream(numbers: Iterator[int]) -> int:
|
||||
"""流式输入:对应 Go 侧传入 chan int 参数"""
|
||||
return sum(numbers)
|
||||
|
||||
|
||||
@gobridge
|
||||
def double_stream(numbers: Iterator[int]) -> Iterator[int]:
|
||||
"""双向流:输入每个数,yield 其平方,对应 Go 侧 Invoke[chan int](c, ctx, "double_stream", inputChan)"""
|
||||
for n in numbers:
|
||||
yield n * n
|
||||
|
||||
|
||||
# ── struct(dict)类型 ──────────────────────────────────────────────────────
|
||||
|
||||
@gobridge
|
||||
def get_user(uid: int) -> dict:
|
||||
"""普通调用:返回一个 struct(Go 对应 User)"""
|
||||
return {"id": uid, "name": f"user_{uid}", "score": uid * 1.5}
|
||||
|
||||
|
||||
@gobridge
|
||||
def total_score(users: list) -> float:
|
||||
"""slice 输入:接收 []User,返回总分"""
|
||||
return sum(u["score"] for u in users)
|
||||
|
||||
|
||||
@gobridge
|
||||
def enrich_users(users: list) -> list:
|
||||
"""slice 输入输出:为每个 user 追加 level 字段"""
|
||||
result = []
|
||||
for u in users:
|
||||
u = dict(u)
|
||||
u["level"] = "gold" if u["score"] >= 10 else "silver"
|
||||
result.append(u)
|
||||
return result
|
||||
|
||||
|
||||
# ── struct/slice 流式组合 ────────────────────────────────────────────────────
|
||||
|
||||
@gobridge
|
||||
def gen_users(count: int) -> Iterator[dict]:
|
||||
"""流式输出 struct:yield 多个 User,对应 Go 侧 Invoke[chan User]"""
|
||||
for i in range(1, count + 1):
|
||||
yield {"id": i, "name": f"user_{i}", "score": float(i * 3)}
|
||||
|
||||
|
||||
@gobridge
|
||||
def process_users(users: Iterator[dict]) -> Iterator[dict]:
|
||||
"""双向流 struct:输入流式 User,yield 处理后的 User"""
|
||||
for u in users:
|
||||
yield {"id": u["id"], "name": u["name"].upper(), "score": u["score"] * 2}
|
||||
|
||||
|
||||
run()
|
||||
Reference in New Issue
Block a user