add migration capability with north

This commit is contained in:
xenia 2020-11-13 20:16:45 -05:00
parent 45271e2bac
commit 245c6b7dbb
6 changed files with 77 additions and 42 deletions

2
.envrc
View File

@ -1 +1,3 @@
export LD_LIBRARY_PATH="$PWD/lib:$LD_LIBRARY_PATH"
export DATABASE_URL="sqlite:lib/crossfire.sqlite"
[ ! -d lib ] && mkdir lib

1
.gitignore vendored
View File

@ -4,5 +4,6 @@
*.zo
*.dep
*.so
*.sqlite
/crossfire/compiled/
/crossfire/doc/

View File

@ -17,7 +17,8 @@
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
(require racket/async-channel racket/bool racket/engine racket/fasl racket/function racket/list
racket/match racket/tcp
racket/match racket/tcp syntax/parse/define
(for-syntax racket/base racket/syntax)
"not-crypto.rkt")
;; define message types (they must all be prefab for fasl)
@ -490,6 +491,45 @@
(provide make-transaction-manager tm-register-rpc tm-deregister-rpc tm-transact tm-shutdown)
;; utility functions and macros for defining rpcs
;; id generation helpers
(define-for-syntax (rpc-type-id what)
(format-id what "rpc-type-~a" (syntax-e what)))
(define-for-syntax (rpc-impl-id what)
(format-id what "rpc-impl-~a" (syntax-e what)))
;; parameters for comms, tm, and targeted node
(define current-comms (make-parameter #f))
(define current-tm (make-parameter #f))
(define current-to-node (make-parameter #f))
;; defines a class of rpcs
(define-simple-macro (define-rpc-type type:id)
#:with def-id (rpc-type-id #'type)
(define def-id (make-hash)))
;; defines an rpc implementation, registers it with a given class of rpcs and makes a wrapper to
;; call it
(define-simple-macro (define-rpc type:id (name:id args:id ...) body:expr ...)
#:with def-id (rpc-type-id #'type)
#:with impl-id (rpc-impl-id #'name)
(begin
(define (impl-id args ...) body ...)
(define (name args ...)
(tm-transact (current-tm) (current-to-node) (quote name) (list args ...)))
(hash-set! def-id (quote name) impl-id)))
;; installs all rpcs of a given rpc class into the transaction manager
(define-simple-macro (install-rpc-type type:id)
#:with def-id (rpc-type-id #'type)
(for ([(k v) (in-hash def-id)])
(tm-register-rpc (current-tm) k v)))
(provide current-comms current-tm current-to-node
define-rpc-type define-rpc install-rpc-type)
; ;; demo code
; (define server-sk #"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
; (define server-pk (crypto-sign-public-key server-sk))

View File

@ -21,6 +21,7 @@
(define pkg-authors '(haskal))
(define collection "crossfire")
(define deps '("base"))
(define deps '("base" "db-lib" "scribble-text-lib"
"north"))
(define build-deps '("scribble-lib" "racket-doc" "rackunit-lib"))
(define scribblings '(("scribblings/crossfire.scrbl" ())))

View File

@ -0,0 +1,11 @@
#lang north
-- @revision: e50ab485d8590ead53c2518396c04f81
-- @description: Creates the tasks table.
-- @up {
create table tasks (id integer primary key, name text not null, manifest blob not null);
-- }
-- @down {
drop table tasks;
-- }

View File

@ -16,48 +16,31 @@
;; You should have received a copy of the GNU Affero General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
(require "comms.rkt" "not-crypto.rkt"
syntax/parse/define
(for-syntax racket/base racket/syntax))
(require db/base db/sqlite3 racket/path
"comms.rkt" "not-crypto.rkt")
;; utility functions and macros for defining rpcs
;; configuration
;; id generation helpers
(define-for-syntax (rpc-type-id what)
(format-id what "rpc-type-~a" (syntax-e what)))
(define-for-syntax (rpc-impl-id what)
(format-id what "rpc-impl-~a" (syntax-e what)))
(define PRODUCTION? #f)
;; parameters for comms, tm, and targeted node
(define current-comms (make-parameter #f))
(define current-tm (make-parameter #f))
(define current-to-node (make-parameter #f))
;; defines a class of rpcs
(define-simple-macro (define-rpc-type type:id)
#:with def-id (rpc-type-id #'type)
(define def-id (make-hash)))
;; defines an rpc implementation, registers it with a given class of rpcs and makes a wrapper to
;; call it
(define-simple-macro (define-rpc type:id (name:id args:id ...) body:expr ...)
#:with def-id (rpc-type-id #'type)
#:with impl-id (rpc-impl-id #'name)
(begin
(define (impl-id args ...) body ...)
(define (name args ...)
(tm-transact (current-tm) (current-to-node) (quote name) (list args ...)))
(hash-set! def-id (quote name) impl-id)))
;; installs all rpcs of a given rpc class into the transaction manager
(define-simple-macro (install-rpc-type type:id)
#:with def-id (rpc-type-id #'type)
(for ([(k v) (in-hash def-id)])
(tm-register-rpc (current-tm) k v)))
(define SERVER-DATA-DIR (if PRODUCTION? "/var/lib/crossfire/" "lib/"))
(define SERVER-DB-PATH (build-path SERVER-DATA-DIR "crossfire.sqlite"))
;; ok now we get to the real stuff
;; server rpc functions
;; database
(define (open-server-db)
(sqlite3-connect #:database SERVER-DB-PATH))
(define current-db (make-parameter #f))
(define (with-server-db proc)
(parameterize ([current-db (open-server-db)])
(proc)
(disconnect (current-db))))
;; rpc calls
(define-rpc-type server)
@ -67,6 +50,3 @@
(add1 a))
;; agent rpc functions
;; TODO ...