Browse Source

Rename gatekeeping/privilege to something more paletable

While not strictly false, we don't want to encourage gatekeeping
everywhere.
add-remove-to-filo-queue
Christopher Lemmer Webber 6 years ago
parent
commit
0c13fc15a8
No known key found for this signature in database
GPG Key ID: 4BC025925FF8F4D3
  1. 82
      goblins/actor-lib/gatekeep.rkt

82
goblins/actor-lib/gatekeep.rkt

@ -1,11 +1,11 @@
#lang racket/base
(provide spawn-gatekeeper-pair
gatekeep
^energized)
(provide spawn-warden-pair
ward
^enchanted)
;; This module provides a "gatekeeping" mechanism... behind the
;; gate is some interesting behavior an actor might not quite
;; This module provides a "warding" mechanism... behind the
;; ward is some interesting behavior an actor might not quite
;; everyone to have access to. See the tests for how to use.
;; See also http://www.erights.org/history/joule/MANUAL.B17.pdf
@ -16,39 +16,39 @@
racket/match)
;; Keyword arguments:
;; - #:async?: If true, the energizer will use <- instead of $ to
;; - #:async?: If true, the incanter will use <- instead of $ to
;; proxy messages sends
;;
;; Returns two values to its continuation:
;; - a gatekeeper, to be used with the gatekeep procedure below
;; - an energizer, to access actors which have gatekept methods
(define (spawn-gatekeeper-pair #:async? [async? #f])
;; - a warden, to be used with the ward procedure below
;; - an incanter, to access actors which have warded methods
(define (spawn-warden-pair #:async? [async? #f])
(define-values (seal unseal sealed?)
(make-sealer-triplet 'gatekeep))
;; When invoked, the gatekeeper returns either:
(make-sealer-triplet 'ward))
;; When invoked, the warden returns either:
;; - #f: if these are not arguments sealed by the sealer, or
;; - (list kws kw-vals args): the unsealed arguments
(define (^gatekeeper _bcom)
(define (^warden _bcom)
(lambda (maybe-sealed-args)
(and (sealed? maybe-sealed-args)
(unseal maybe-sealed-args))))
(define (^energizer _bcom)
(define (^incanter _bcom)
(define $/<-
(if async? <- $))
(make-keyword-procedure
(lambda (kws kw-args target . args)
($/<- target (seal (list kws kw-args args))))))
(values (spawn ^gatekeeper) (spawn ^energizer)))
(values (spawn ^warden) (spawn ^incanter)))
(define (gatekeep gatekeeper behavior
#:extends [extends #f])
(define (ward warden behavior
#:extends [extends #f])
(define (error-out)
(error "Not sealed args and no extended behavior"))
(make-keyword-procedure
(match-lambda*
[(list '() '() maybe-sealed-args)
(match ($ gatekeeper maybe-sealed-args)
(match ($ warden maybe-sealed-args)
[(list kws kw-vals args)
(keyword-apply behavior kws kw-vals args)]
;; Hm, didn't match the seal, so let's use the extended
@ -64,22 +64,22 @@
(keyword-apply extends kws kw-vals args)
(error-out))])))
;; Sets up an "energized proxy" that always sends messages through
;; the energizer
(define (^energized _bcom energizer target
;; Sets up an "enchanted proxy" that always sends messages through
;; the incanter
(define (^enchanted _bcom incanter target
#:async? [async? #f])
(define $/<-
(if async? <- $))
(make-keyword-procedure
(lambda (kws kw-vals . args)
(keyword-apply $/<- kws kw-vals energizer target args))))
(keyword-apply $/<- kws kw-vals incanter target args))))
(module+ test
(require "methods.rkt"
rackunit
racket/contract)
(define (^inbox bcom mailbox-name admin-gatekeeper)
(define (^inbox bcom mailbox-name admin-warden)
(define (make-main-beh mailbox-name messages)
(define admin-methods
(methods
@ -98,7 +98,7 @@
(bcom mailbox-name (make-main-beh msg messages))]
[(mailbox-name) mailbox-name]))
(gatekeep admin-gatekeeper admin-methods
(ward admin-warden admin-methods
#:extends public-methods))
(define revoked-beh
@ -108,61 +108,61 @@
(define am (make-actormap))
(match-define (list inbox admin-energizer)
(match-define (list inbox admin-incanter)
(actormap-run! am
(lambda ()
(define-values (admin-gatekeeper admin-energizer)
(spawn-gatekeeper-pair))
(list (spawn ^inbox "My First Inbox" admin-gatekeeper)
admin-energizer))))
(define-values (admin-warden admin-incanter)
(spawn-warden-pair))
(list (spawn ^inbox "My First Inbox" admin-warden)
admin-incanter))))
(check-equal?
(actormap-peek am inbox 'mailbox-name)
"My First Inbox")
(test-exn
"Can't just set the name without energizer"
"Can't just set the name without incanter"
any/c
(lambda ()
(actormap-poke! am inbox 'set-name "A brand new name")))
(test-not-exn
"Can set the name through the energizer without erroring out"
"Can set the name through the incanter without erroring out"
(lambda ()
(actormap-poke! am admin-energizer
(actormap-poke! am admin-incanter
inbox 'set-name "New name"
#:upcase? #t)))
(test-equal?
"New name successfully set via energizer"
"New name successfully set via incanter"
(actormap-peek am inbox 'mailbox-name)
"NEW NAME")
(define some-other-energizer
(define some-other-incanter
(actormap-run! am
(lambda ()
(define-values (_some-gatekeeper some-energizer)
(spawn-gatekeeper-pair))
some-energizer)))
(define-values (_some-warden some-incanter)
(spawn-warden-pair))
some-incanter)))
(test-exn
"Can't just set the name without energizer"
"Can't just set the name without incanter"
any/c
(lambda ()
(actormap-poke! am some-other-energizer
(actormap-poke! am some-other-incanter
inbox 'set-name "A brand new name")))
(define inbox-admin
(actormap-spawn! am ^energized admin-energizer inbox))
(actormap-spawn! am ^enchanted admin-incanter inbox))
(test-not-exn
"Can set the name through the energized proxy without erroring out"
"Can set the name through the enchanted proxy without erroring out"
(lambda ()
(actormap-poke! am inbox-admin
'set-name "Another new name"
#:upcase? #t)))
(test-equal?
"New name successfully set via energized proxy"
"New name successfully set via enchanted proxy"
(actormap-peek am inbox 'mailbox-name)
"ANOTHER NEW NAME"))

Loading…
Cancel
Save