mirror of
https://github.com/EchoVault/SugarDB.git
synced 2025-10-13 19:55:14 +08:00
Added plugins folder location in config for the server.
Created get and ser plugin files. Created server function to load plugins. Moved Makefile inside server folder to build and run server.
This commit is contained in:
11
server/Makefile
Normal file
11
server/Makefile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
build-plugins:
|
||||||
|
go build -buildmode=plugin -o bin/plugins/commands/command_get.so plugins/commands/get/get.go
|
||||||
|
go build -buildmode=plugin -o bin/plugins/commands/command_set.so plugins/commands/set/set.go
|
||||||
|
|
||||||
|
build-server:
|
||||||
|
go build -o bin/server ./*.go
|
||||||
|
|
||||||
|
build: build-plugins build-server
|
||||||
|
|
||||||
|
run:
|
||||||
|
./bin/server
|
@@ -5,22 +5,35 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"plugin"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/kelvinmwinuka/memstore/serialization"
|
"github.com/kelvinmwinuka/memstore/serialization"
|
||||||
"github.com/kelvinmwinuka/memstore/utils"
|
"github.com/kelvinmwinuka/memstore/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Plugin interface {
|
||||||
|
Name() string
|
||||||
|
Command() string
|
||||||
|
Description() string
|
||||||
|
HandleCommand(tokens []string, server interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
data map[string]interface{}
|
data map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
config utils.Config
|
config utils.Config
|
||||||
data Data
|
data Data
|
||||||
|
plugins []Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) handleConnection(conn net.Conn) {
|
func (server *Server) handleConnection(conn net.Conn) {
|
||||||
@@ -116,11 +129,69 @@ func (server *Server) StartHTTP() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (server *Server) LoadPlugins() {
|
||||||
|
conf := server.config
|
||||||
|
|
||||||
|
// Load plugins
|
||||||
|
pluginDirs, err := ioutil.ReadDir(conf.Plugins)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range pluginDirs {
|
||||||
|
if file.IsDir() {
|
||||||
|
switch file.Name() {
|
||||||
|
case "commands":
|
||||||
|
files, err := ioutil.ReadDir(path.Join(conf.Plugins, "commands"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
if !strings.HasSuffix(file.Name(), ".so") {
|
||||||
|
// Skip files that are not .so
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p, err := plugin.Open(path.Join(conf.Plugins, "commands", file.Name()))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginSymbol, err := p.Lookup("Plugin")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("unexpected plugin symbol in plugin %s\n", file.Name())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin, ok := pluginSymbol.(Plugin)
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("invalid plugin signature in plugin %s \n", file.Name())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a plugin that handles the same command already exists
|
||||||
|
for _, loadedPlugin := range server.plugins {
|
||||||
|
if loadedPlugin.Command() == plugin.Command() {
|
||||||
|
fmt.Printf("plugin that handles %s command already exists. Please handle a different command.", plugin.Command())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.plugins = append(server.plugins, plugin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (server *Server) Start() {
|
func (server *Server) Start() {
|
||||||
server.data.data = make(map[string]interface{})
|
server.data.data = make(map[string]interface{})
|
||||||
|
|
||||||
conf := server.config
|
conf := server.config
|
||||||
|
|
||||||
|
server.LoadPlugins()
|
||||||
|
|
||||||
if conf.TLS && (len(conf.Key) <= 0 || len(conf.Cert) <= 0) {
|
if conf.TLS && (len(conf.Key) <= 0 || len(conf.Cert) <= 0) {
|
||||||
fmt.Println("Must provide key and certificate file paths for TLS mode.")
|
fmt.Println("Must provide key and certificate file paths for TLS mode.")
|
||||||
return
|
return
|
||||||
@@ -134,10 +205,9 @@ func (server *Server) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
conf := utils.GetConfig()
|
|
||||||
|
|
||||||
server := Server{
|
server := Server{
|
||||||
config: conf,
|
config: utils.GetConfig(),
|
||||||
|
plugins: []Plugin{},
|
||||||
}
|
}
|
||||||
|
|
||||||
server.Start()
|
server.Start()
|
||||||
|
36
server/plugins/commands/get/get.go
Normal file
36
server/plugins/commands/get/get.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Server interface {
|
||||||
|
GetData(key string) interface{}
|
||||||
|
SetData(key string, value interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
name string
|
||||||
|
command string
|
||||||
|
description string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Plugin plugin
|
||||||
|
|
||||||
|
func (p *plugin) Name() string {
|
||||||
|
return p.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Command() string {
|
||||||
|
return p.command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Description() string {
|
||||||
|
return p.description
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) HandleCommand(tokens []string, server interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Plugin.name = "GetCommand"
|
||||||
|
Plugin.command = "get"
|
||||||
|
Plugin.description = "Get the value from the specified key"
|
||||||
|
}
|
36
server/plugins/commands/set/set.go
Normal file
36
server/plugins/commands/set/set.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type Server interface {
|
||||||
|
GetData(key string) interface{}
|
||||||
|
SetData(key string, value interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
name string
|
||||||
|
command string
|
||||||
|
description string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Plugin plugin
|
||||||
|
|
||||||
|
func (p *plugin) Name() string {
|
||||||
|
return p.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Command() string {
|
||||||
|
return p.command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) Description() string {
|
||||||
|
return p.description
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *plugin) HandleCommand(tokens []string, server interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Plugin.name = "SetCommand"
|
||||||
|
Plugin.command = "set"
|
||||||
|
Plugin.description = "Set the value of the specified key"
|
||||||
|
}
|
Reference in New Issue
Block a user