-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement pluggable session store and make it threadsafe
- Loading branch information
Showing
16 changed files
with
707 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export GOPATH="$(pwd)/.gopath" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Package config provides the RiveScript configuration type. | ||
package config | ||
|
||
import ( | ||
"github.com/aichaos/rivescript-go/sessions" | ||
"github.com/aichaos/rivescript-go/sessions/memory" | ||
) | ||
|
||
// Type Config configures a RiveScript instance. | ||
type Config struct { | ||
// Debug enables verbose debug logging to your standard output. | ||
Debug bool | ||
|
||
// Strict enables strict syntax checking. | ||
Strict bool | ||
|
||
// Depth sets the recursion depth limit. The zero value will default to | ||
// 50 levels deep. | ||
Depth uint | ||
|
||
// UTF8 enables UTF-8 support for user messages and triggers. | ||
UTF8 bool | ||
|
||
// SessionManager chooses a session manager for user variables. | ||
SessionManager sessions.SessionManager | ||
} | ||
|
||
// Basic creates a default configuration: | ||
// | ||
// - Strict: true | ||
// - Depth: 50 | ||
// - UTF8: false | ||
func Basic() *Config { | ||
return &Config{ | ||
Strict: true, | ||
Depth: 50, | ||
UTF8: false, | ||
SessionManager: memory.New(), | ||
} | ||
} | ||
|
||
// UTF8 creates a default configuration with UTF-8 mode enabled. | ||
// | ||
// - Strict: true | ||
// - Depth: 50 | ||
// - UTF8: true | ||
func UTF8() *Config { | ||
return &Config{ | ||
Strict: true, | ||
Depth: 50, | ||
UTF8: true, | ||
SessionManager: memory.New(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Package sessions provides the interface and default session store for | ||
// RiveScript. | ||
package sessions | ||
|
||
/* | ||
Interface SessionManager describes a session manager for user variables | ||
in RiveScript. | ||
The session manager keeps track of getting and setting user variables, | ||
for example when the `<set>` or `<get>` tags are used in RiveScript | ||
or when API functions like `SetUservar()` are called. | ||
By default RiveScript stores user sessions in memory and provides methods | ||
to export and import them (e.g. to persist them when the bot shuts down | ||
so they can be reloaded). If you'd prefer a more 'active' session storage, | ||
for example one that puts user variables into a database or cache, you can | ||
create your own session manager that implements this interface. | ||
*/ | ||
type SessionManager interface { | ||
// Init makes sure a username has a session (creates one if not). It returns | ||
// the pointer to the user data in either case. | ||
Init(username string) *UserData | ||
|
||
// Set user variables from a map. | ||
Set(username string, vars map[string]string) | ||
|
||
// AddHistory adds input and reply to the user's history. | ||
AddHistory(username, input, reply string) | ||
|
||
// SetLastMatch sets the last matched trigger. | ||
SetLastMatch(username, trigger string) | ||
|
||
// Get a user variable. | ||
Get(username string, key string) (string, error) | ||
|
||
// Get all variables for a user. | ||
GetAny(username string) (*UserData, error) | ||
|
||
// Get all variables about all users. | ||
GetAll() map[string]*UserData | ||
|
||
// GetLastMatch returns the last trigger the user matched. | ||
GetLastMatch(username string) (string, error) | ||
|
||
// GetHistory returns the user's history. | ||
GetHistory(username string) (*History, error) | ||
|
||
// Clear all variables for a given user. | ||
Clear(username string) | ||
|
||
// Clear all variables for all users. | ||
ClearAll() | ||
|
||
// Freeze makes a snapshot of a user's variables. | ||
Freeze(string) error | ||
|
||
// Thaw unfreezes a snapshot of a user's variables and returns an error | ||
// if the user had no frozen variables. | ||
Thaw(username string, ThawAction ThawAction) error | ||
} | ||
|
||
// HistorySize is the number of entries stored in the history. | ||
const HistorySize int = 9 | ||
|
||
// Type UserData is a container for user variables. | ||
type UserData struct { | ||
Variables map[string]string | ||
LastMatch string | ||
*History | ||
} | ||
|
||
// Type History keeps track of recent input and reply history. | ||
type History struct { | ||
Input []string | ||
Reply []string | ||
} | ||
|
||
// NewHistory creates a new History object with the history arrays filled out. | ||
func NewHistory() *History { | ||
h := &History{ | ||
Input: []string{}, | ||
Reply: []string{}, | ||
} | ||
|
||
for i := 0; i < HistorySize; i++ { | ||
h.Input = append(h.Input, "undefined") | ||
h.Reply = append(h.Reply, "undefined") | ||
} | ||
|
||
return h | ||
} | ||
|
||
// Type ThawAction describes the action for the `Thaw()` method. | ||
type ThawAction int | ||
|
||
// Valid options for ThawAction. | ||
const ( | ||
// Thaw means to restore the user variables and erase the frozen copy. | ||
Thaw = iota | ||
|
||
// Discard means to cancel the frozen copy and not restore them. | ||
Discard | ||
|
||
// Keep means to restore the user variables and still keep the frozen copy. | ||
Keep | ||
) |
Oops, something went wrong.