feature
2015-03-16
feature/flag.go
First pass at an implementation. Implement the calculation to determine whether a string is included in the partition or not, using crc32 to coerce the string to an evenly distributed uint32, and a modulo to turn it into a percentage. Implement a store to keep track of available flags and the level of the partition for each flag. Implement an API to retrieve, create, and modify these available flags.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/flag.go Mon Mar 16 22:45:58 2015 -0400 1.3 @@ -0,0 +1,52 @@ 1.4 +package feature 1.5 + 1.6 +import ( 1.7 + "hash/crc32" 1.8 + "log" 1.9 +) 1.10 + 1.11 +type Flag struct { 1.12 + ID string 1.13 + Limit int 1.14 +} 1.15 + 1.16 +func (f Flag) calcOffset() int { 1.17 + return calcValue(f.ID) 1.18 +} 1.19 + 1.20 +func (f Flag) Permit(candidate string) bool { 1.21 + if f.Limit >= 100 { 1.22 + return true 1.23 + } 1.24 + if f.Limit <= 0 { 1.25 + return false 1.26 + } 1.27 + return (calcValue(candidate)+f.calcOffset())%100 <= f.Limit 1.28 +} 1.29 + 1.30 +type FlagSet struct { 1.31 + flags map[string]bool 1.32 +} 1.33 + 1.34 +func (set FlagSet) Check(flag string) bool { 1.35 + pass, ok := set.flags[flag] 1.36 + if !ok { 1.37 + log.Println("Checked for flag that wasn't in response:", flag) 1.38 + pass = false 1.39 + } 1.40 + return pass 1.41 +} 1.42 + 1.43 +func calcValue(in string) int { 1.44 + return int(crc32.ChecksumIEEE([]byte(in)) % 100) 1.45 +} 1.46 + 1.47 +/* 1.48 + 1.49 +Client has one function: 1.50 + 1.51 +1. func (c Client) Load(in string) FlagSet -- loads the flagset with "in" as the parameter to gate on 1.52 + 1.53 +// TODO Have the client cache FlagSets in memory by the parameter being gated on; we can reuse FlagSets for a minute or two 1.54 + 1.55 +*/