|
package main |
|
|
|
import ( |
|
"fmt" |
|
"io/ioutil" |
|
"log" |
|
"os" |
|
"os/exec" |
|
"path/filepath" |
|
"sync" |
|
"syscall" |
|
) |
|
|
|
type Plugin interface { |
|
Process(data string) (string, error) |
|
} |
|
|
|
func main() { |
|
// Create a directory for the named pipes |
|
pipeDir := "./pipes" |
|
err := os.MkdirAll(pipeDir, 0755) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
|
|
// Start the plugin processes |
|
pluginPaths := []string{"./plugins/plugin1", "./plugins/plugin2"} |
|
|
|
var wg sync.WaitGroup |
|
for _, pluginPath := range pluginPaths { |
|
wg.Add(1) |
|
go startPluginProcess(pluginPath, &wg) |
|
} |
|
|
|
// Wait for the plugin processes to start |
|
wg.Wait() |
|
|
|
// Send data to the plugins |
|
data := "Hello, plugins!" |
|
|
|
for _, pluginPath := range pluginPaths { |
|
result, err := sendDataToPlugin(data, pluginPath) |
|
if err != nil { |
|
log.Printf("Error sending data to plugin %s: %v", pluginPath, err) |
|
continue |
|
} |
|
|
|
fmt.Printf("Plugin %s processed data: %s\n", pluginPath, result) |
|
} |
|
|
|
// Cleanup the named pipes |
|
err = os.RemoveAll(pipeDir) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
} |
|
|
|
func startPluginProcess(pluginPath string, wg *sync.WaitGroup) { |
|
defer wg.Done() |
|
|
|
// Create a named pipe for the plugin process |
|
pipePath := filepath.Join("./pipes", filepath.Base(pluginPath)) |
|
err := syscall.Mkfifo(pipePath, 0666) |
|
if err != nil { |
|
log.Printf("Error creating named pipe for plugin %s: %v", pluginPath, err) |
|
return |
|
} |
|
|
|
// Start the plugin process |
|
cmd := exec.Command(pluginPath, pipePath) |
|
err = cmd.Start() |
|
if err != nil { |
|
log.Printf("Error starting plugin %s: %v", pluginPath, err) |
|
return |
|
} |
|
|
|
log.Printf("Plugin %s started", pluginPath) |
|
|
|
// Wait for the plugin process to exit |
|
err = cmd.Wait() |
|
if err != nil { |
|
log.Printf("Plugin %s exited with error: %v", pluginPath, err) |
|
} else { |
|
log.Printf("Plugin %s exited successfully", pluginPath) |
|
} |
|
|
|
// Remove the named pipe |
|
err = os.Remove(pipePath) |
|
if err != nil { |
|
log.Printf("Error removing named pipe for plugin %s: %v", pluginPath, err) |
|
} |
|
} |
|
|
|
func sendDataToPlugin(data string, pluginPath string) (string, error) { |
|
// Open the named pipe for writing |
|
pipePath := filepath.Join("./pipes", filepath.Base(pluginPath)) |
|
pipe, err := os.OpenFile(pipePath, os.O_WRONLY, os.ModeNamedPipe) |
|
if err != nil { |
|
return "", err |
|
} |
|
defer pipe.Close() |
|
|
|
// Write the data to the named pipe |
|
_, err = pipe.WriteString(data) |
|
if err != nil { |
|
return "", err |
|
} |
|
|
|
// Read the result from the named pipe |
|
result, err := ioutil.ReadFile(pipePath) |
|
if err != nil { |
|
return "", err |
|
} |
|
|
|
return string(result), nil |
|
} |