feat(ctx): basic ctx setup
This commit is contained in:
parent
2181e82f62
commit
53b779b801
7 changed files with 105 additions and 89 deletions
|
|
@ -3,18 +3,19 @@ package main
|
||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
|
||||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers"
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers"
|
||||||
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/server"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server := rpc.NewServer()
|
server := server.NewServer()
|
||||||
|
|
||||||
server.Register("initialize", handlers.InitializeHandler{})
|
server.Register("initialize", handlers.InitializeHandler{})
|
||||||
|
|
||||||
if err := server.Serve(os.Stdin, os.Stdout); err != nil {
|
if err := server.Run(os.Stdin, os.Stdout); err != nil {
|
||||||
slog.Error("server error", "error", err)
|
slog.Error("server error", "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,12 @@ func (h CreateNoteHandler) Handle(ctx context.Context, params []byte) (*rpc.Resp
|
||||||
return nil, h.ReturnError(err)
|
return nil, h.ReturnError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.tagRepo.Upsert(tags)
|
err = h.tagRepo.Upsert(ctx, tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, h.ReturnError(err)
|
return nil, h.ReturnError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.noteRepo.Upsert(cmd.Title, cmd.Path, frontmatter.Slugify(cmd.Title))
|
err = h.noteRepo.Upsert(ctx, cmd.Title, cmd.Path, frontmatter.Slugify(cmd.Title))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, h.ReturnError(err)
|
return nil, h.ReturnError(err)
|
||||||
}
|
}
|
||||||
12
core/handlers/handler.go
Normal file
12
core/handlers/handler.go
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler interface {
|
||||||
|
Handle(ctx context.Context, raw json.RawMessage) (any, *rpc.Error)
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
||||||
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
|
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
|
||||||
)
|
)
|
||||||
|
|
@ -12,7 +14,7 @@ type initializeCommand struct {
|
||||||
|
|
||||||
type InitializeHandler struct{}
|
type InitializeHandler struct{}
|
||||||
|
|
||||||
func (h InitializeHandler) Handle(raw json.RawMessage) (any, *rpc.Error) {
|
func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, *rpc.Error) {
|
||||||
var params initializeCommand
|
var params initializeCommand
|
||||||
|
|
||||||
if err := json.Unmarshal(raw, ¶ms); err != nil {
|
if err := json.Unmarshal(raw, ¶ms); err != nil {
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
package rpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Handler interface {
|
|
||||||
Handle(json.RawMessage) (any, *Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
handlers map[string]Handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServer() *Server {
|
|
||||||
return &Server{
|
|
||||||
handlers: make(map[string]Handler),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Register(method string, handler Handler) {
|
|
||||||
s.handlers[method] = handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Serve(r io.Reader, w io.Writer) error {
|
|
||||||
scanner := bufio.NewScanner(r)
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Bytes()
|
|
||||||
var req Request
|
|
||||||
if err := json.Unmarshal(line, &req); err != nil {
|
|
||||||
s.write(w, Response{
|
|
||||||
Jsonrpc: "2.0",
|
|
||||||
Error: &Error{Code: -32700, Message: "parse error"},
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
s.handle(w, req)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return scanner.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) handle(w io.Writer, req Request) {
|
|
||||||
handler, ok := s.handlers[req.Method]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
s.respond(w, req.ID, nil, &Error{
|
|
||||||
Code: -32601,
|
|
||||||
Message: "method not found",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := handler.Handle(req.Params)
|
|
||||||
|
|
||||||
if req.ID == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.respond(w, req.ID, result, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) respond(w io.Writer, id *int, result any, err *Error) {
|
|
||||||
resp := Response{
|
|
||||||
Jsonrpc: "2.0",
|
|
||||||
ID: id,
|
|
||||||
Result: result,
|
|
||||||
Error: err,
|
|
||||||
}
|
|
||||||
|
|
||||||
s.write(w, resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) write(w io.Writer, resp Response) {
|
|
||||||
data, _ := json.Marshal(resp)
|
|
||||||
fmt.Fprintln(w, string(data))
|
|
||||||
}
|
|
||||||
84
core/server/server.go
Normal file
84
core/server/server.go
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Package server contains the server running the JSON-RPC 2.0 Protocol.
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers"
|
||||||
|
"github.com/KristianJBorgwarth/dendrite.daemon/core/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
handlers map[string]handlers.Handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServer() *Server {
|
||||||
|
return &Server{
|
||||||
|
handlers: make(map[string]handlers.Handler),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Register(method string, handler handlers.Handler) {
|
||||||
|
s.handlers[method] = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Run(r io.Reader, w io.Writer) error {
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Bytes()
|
||||||
|
var req rpc.Request
|
||||||
|
if err := json.Unmarshal(line, &req); err != nil {
|
||||||
|
s.write(w, rpc.Response{
|
||||||
|
Jsonrpc: "2.0",
|
||||||
|
Error: &rpc.Error{Code: -32700, Message: "parse error"},
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s.handle(w, req)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) handle(w io.Writer, req rpc.Request) {
|
||||||
|
ctx := context.Background()
|
||||||
|
handler, ok := s.handlers[req.Method]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
s.respond(w, req.ID, nil, &rpc.Error{
|
||||||
|
Code: -32601,
|
||||||
|
Message: "method not found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := handler.Handle(ctx, req.Params)
|
||||||
|
|
||||||
|
if req.ID == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.respond(w, req.ID, result, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) {
|
||||||
|
resp := rpc.Response{
|
||||||
|
Jsonrpc: "2.0",
|
||||||
|
ID: id,
|
||||||
|
Result: result,
|
||||||
|
Error: err,
|
||||||
|
}
|
||||||
|
|
||||||
|
s.write(w, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) write(w io.Writer, resp rpc.Response) {
|
||||||
|
data, _ := json.Marshal(resp)
|
||||||
|
fmt.Fprintln(w, string(data))
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue