github.com/hashicorp/go-plugin@v1.6.0/examples/bidirectional/main.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package main 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 "log" 10 "os" 11 "os/exec" 12 "strconv" 13 14 "github.com/hashicorp/go-plugin" 15 "github.com/hashicorp/go-plugin/examples/bidirectional/shared" 16 ) 17 18 type addHelper struct{} 19 20 func (*addHelper) Sum(a, b int64) (int64, error) { 21 return a + b, nil 22 } 23 24 func main() { 25 // We don't want to see the plugin logs. 26 log.SetOutput(ioutil.Discard) 27 28 // We're a host. Start by launching the plugin process. 29 client := plugin.NewClient(&plugin.ClientConfig{ 30 HandshakeConfig: shared.Handshake, 31 Plugins: shared.PluginMap, 32 Cmd: exec.Command("sh", "-c", os.Getenv("COUNTER_PLUGIN")), 33 AllowedProtocols: []plugin.Protocol{ 34 plugin.ProtocolNetRPC, plugin.ProtocolGRPC}, 35 }) 36 defer client.Kill() 37 38 // Connect via RPC 39 rpcClient, err := client.Client() 40 if err != nil { 41 fmt.Println("Error:", err.Error()) 42 os.Exit(1) 43 } 44 45 // Request the plugin 46 raw, err := rpcClient.Dispense("counter") 47 if err != nil { 48 fmt.Println("Error:", err.Error()) 49 os.Exit(1) 50 } 51 52 // We should have a Counter store now! This feels like a normal interface 53 // implementation but is in fact over an RPC connection. 54 counter := raw.(shared.Counter) 55 56 os.Args = os.Args[1:] 57 switch os.Args[0] { 58 case "get": 59 result, err := counter.Get(os.Args[1]) 60 if err != nil { 61 fmt.Println("Error:", err.Error()) 62 os.Exit(1) 63 } 64 65 fmt.Println(result) 66 67 case "put": 68 i, err := strconv.Atoi(os.Args[2]) 69 if err != nil { 70 fmt.Println("Error:", err.Error()) 71 os.Exit(1) 72 } 73 74 err = counter.Put(os.Args[1], int64(i), &addHelper{}) 75 if err != nil { 76 fmt.Println("Error:", err.Error()) 77 os.Exit(1) 78 } 79 80 default: 81 fmt.Println("Please only use 'get' or 'put'") 82 os.Exit(1) 83 } 84 }