// Function serialize sub command of stats "conns" func (s *ServerStat) Conns() []string { var arr []string for _, value := range s.Connections { arr = append(arr, "<NULL>:addr "+value.Addr, "<NULL>:state "+value.State, "<NULL>:secs_since_last_cmd "+tools.IntToString(time.Now().Unix()-value.Cmd_hit_ts)) } return arr }
// Implements get method // Passed boolean param cas - defines of returning cas_unique func (enum *Ascii_protocol_enum) get(storage *cache.LRUCache, cas bool) (string, error) { var result = "" for _, value := range enum.key { item := storage.Get(value) if item != nil { data := tools.ExtractStoredData(item.Cacheable) if data == nil { continue } result += "VALUE " + value + " " + tools.IntToString(int64(item.Flags)) + " " + tools.IntToString(int64(len(data))) if cas { cas_id := tools.GenerateCasId() storage.SetCas(value, cas_id) result += " " + tools.IntToString(cas_id) } result += "\r\n" result += string(data) + "\r\n" } } return result + "END\r\n", nil }
// Function serialize sub command of stats "settings" func (s *ServerStat) Settings(storage *cache.LRUCache) map[string]string { dict := make(map[string]string) dict["maxbytes"] = tools.IntToString(storage.Capacity()) dict["maxconns"] = tools.IntToString(int64(s.Connections_limit)) dict["tcpport"] = s.tcp dict["udpport"] = s.udp dict["verbosity"] = tools.IntToString(int64(s.verbosity)) dict["num_goroutines"] = tools.IntToString(int64(runtime.NumGoroutine())) dict["evictions"] = "on" //TODO: to think about apportunity of another value. if storage.Crawler.Enabled() { dict["lru_crawler"] = "true" } else { dict["lru_crawler"] = "false" } dict["lru_crawler_sleep"] = tools.IntToString(int64(storage.Crawler.Sleep())) dict["lru_crawler_tocrawl"] = tools.IntToString(int64(storage.Crawler.ItemsPerRun)) if s.cas_disabled { dict["cas_enabled"] = "false" } else { dict["cas_enabled"] = "true" } if s.flush_disabled { dict["flush_all_enabled"] = "false" } else { dict["flush_all_enabled"] = "true" } return dict }
// Utility method, for joining common parts of incr/decr methods. // Receives additional param sign, which defines operation: -1 or 1 func (enum *Ascii_protocol_enum) fold(storage *cache.LRUCache, sign int) (string, error) { if item := storage.Get(enum.key[0]); item != nil && (sign == 1 || sign == -1) { existed_data := tools.ExtractStoredData(item.Cacheable) if existed_data != nil { evaluated_data_for_existed, err_for_existed := tools.StringToInt64(string(existed_data)) evaluated_data_for_passed, err_for_passed := tools.StringToUInt64(string(enum.data_string)) if err_for_existed == nil && err_for_passed == nil { var result string if sign > 0 { result = tools.IntToString(evaluated_data_for_existed + int64(evaluated_data_for_passed)) } else { result = tools.IntToString(evaluated_data_for_existed - int64(evaluated_data_for_passed)) } if storage.Set(tools.NewStoredData([]byte(result), enum.key[0]), item.Flags, item.Exptime, 0) { return result + "\r\n", nil } return strings.Replace(SERVER_ERROR_TEMP, "%s", "Not enough memory", 1), errors.New("SERVER_ERROR") } return ERROR_TEMP, nil } } return NOT_FOUND, nil }
// Serialization of sub command items func (s *ServerStat) Items(storage *cache.LRUCache) map[string]string { dict := make(map[string]string) dict["number"] = tools.IntToString(int64(storage.Stats.Current_items)) dict["age"] = tools.IntToString(time.Now().Unix() - storage.Oldest()) dict["expired_unfetched"] = tools.IntToString(int64(storage.Stats.Expired_unfetched)) dict["evicted_unfetched"] = tools.IntToString(int64(storage.Stats.Evicted_unfetched)) dict["crawler_reclaimed"] = tools.IntToString(storage.Stats.Crawler_reclaimed) dict["outofmemory"] = tools.IntToString(storage.Stats.Outofmem) return dict }
func TestHandlingSuiteGets1(t *testing.T) { var storage = cache.New(42) var testEnum = Ascii_protocol_enum{"set", []string{"key"}, 1, 0, 4, 0, false, []byte("TEST"), ""} res, err := testEnum.HandleRequest(storage, nil) testEnum = Ascii_protocol_enum{"gets", []string{"key"}, 0, 0, 0, 0, false, nil, ""} res, err = testEnum.HandleRequest(storage, nil) item := storage.Get("key") if item == nil { t.Fatalf("Item wasn't stored") } cas := item.Cas_unique if cas == 0 { t.Fatalf("Cas unique wasn't set.") } match_str := "VALUE key 1 4 " + tools.IntToString(cas) + "\r\nTEST\r\nEND\r\n" if err != nil || string(res) != match_str { t.Fatalf("Unexpected returned values of handling: ", err, res, testEnum) } }
func main() { tcp_port := flag.String("p", "11211", "TCP Port to listen (non required - default port is 11211)") memory_amount_mb := flag.Int("m", 0, "Amount of memory to allocate (MiB)") daemonize := flag.Bool("d", false, "Run process as background") // unix_socket := flag.String("s", "", "Unix socket path to listen on (disables network support)") // unix_perms := flag.String("a", "", "Permissions (in octal format) for Unix socket created with -s option") listen_ip := flag.String("l", "", "Listen on specified ip addr only; default to any address.") max_connections := flag.Int("c", 1024, "Use max simultaneous connections;") udp_port := flag.String("U", "", "UDP Port to listen (default is empty string - which means it is turned off)") disable_cas := flag.Bool("C", false, "Disabling of cas command support.") disable_flush := flag.Bool("F", false, "Disabling of flush_all command support.") help := flag.Bool("h", false, "Show usage manual and list of options.") verbose := flag.Bool("v", false, "Turning verbosity on. This option includes errors and warnings only.") deep_verbose := flag.Bool("vv", false, "Turning deep verbosity on. This option includes requests, responses and same output as simple verbosity.") flag.Parse() if *help { // TODO: It should be spread in future. fmt.Println("MemoranGo - memory caching service.\nusage:\nmemorango -m <memory_to_alloc> [-CvhFvvd]\n" + "\t[-l <listen_ip>] [-c <limit_connections>] [-p <tcp_port>] [-U <udp_port>]") return } if *memory_amount_mb <= 0 { fmt.Println("Impossible to run server with incorrect specified amount of available data.") return } var verbosity = 0 if *deep_verbose { verbosity = 2 } else if *verbose { verbosity = 1 } if *daemonize { var transacted_options = []string{} dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) transacted_options = append(transacted_options, filepath.Join(dir, os.Args[0]), "-p", *tcp_port, "-m", tools.IntToString(int64(*memory_amount_mb)), "-c", tools.IntToString(int64(*max_connections))) if len(*listen_ip) > 0 { transacted_options = append(transacted_options, "-l", *listen_ip) } if len(*udp_port) > 0 { transacted_options = append(transacted_options, "-U", *udp_port) } if *disable_cas { transacted_options = append(transacted_options, "-C") } if *disable_flush { transacted_options = append(transacted_options, "-F") } if verbosity == 1 { transacted_options = append(transacted_options, "-v") } else if verbosity == 2 { transacted_options = append(transacted_options, "-vv") } transacted_options = append(transacted_options, "&") fmt.Printf("Run %s daemon at 127.0.0.1:%s with %d MiB allowed memory.\n", tools.VERSION, *tcp_port, *memory_amount_mb) cmd := exec.Command("/usr/bin/nohup", transacted_options...) start_err := cmd.Start() if start_err != nil { fmt.Println("Status: ", start_err) } } else { fmt.Printf("%d Run %s on 127.0.0.1:%s with %d MiB allowed memory.\n", os.Getpid(), tools.VERSION, *tcp_port, *memory_amount_mb) _server := server.NewServer(*tcp_port, *udp_port, *listen_ip, *max_connections, *disable_cas, *disable_flush, verbosity, int64(*memory_amount_mb)*1024*1024 /* let's convert to bytes */) _server.RunServer() defer _server.StopServer() _server.Wait() } }
// Function serialize statistic of server and storage and returns it as map of strings func (s *ServerStat) Serialize(storage *cache.LRUCache) map[string]string { dict := make(map[string]string) dict["pid"] = tools.IntToString(int64(s.pid)) dict["uptime"] = tools.IntToString(int64(s.uptime())) dict["time"] = tools.IntToString(int64(s.time())) dict["version"] = tools.VERSION dict["pointer_size"] = tools.IntToString(int64(pointer_size)) secu, mcsecu, secs, mcsecs := s.rusage() dict["rusage_user"] = tools.IntToString(secu) + "." + tools.IntToString(mcsecu) dict["rusage_system"] = tools.IntToString(secs) + "." + tools.IntToString(mcsecs) dict["curr_items"] = tools.IntToString(int64(storage.Stats.Current_items)) dict["total_items"] = tools.IntToString(int64(storage.Stats.Total_items)) dict["bytes"] = tools.IntToString(s.bytes(storage.Capacity())) dict["curr_connections"] = tools.IntToString(int64(s.Current_connections)) dict["total_connections"] = tools.IntToString(int64(s.Total_connections)) dict["evictions"] = tools.IntToString(int64(storage.Stats.Evictions)) dict["expired_unfetched"] = tools.IntToString(int64(storage.Stats.Expired_unfetched)) dict["evicted_unfetched"] = tools.IntToString(int64(storage.Stats.Evicted_unfetched)) dict["bytes_read"] = tools.IntToString(int64(s.Read_bytes)) dict["bytes_written"] = tools.IntToString(int64(s.Written_bytes)) dict["goroutines"] = tools.IntToString(int64(runtime.NumGoroutine())) dict["crawler_reclaimed"] = tools.IntToString(storage.Stats.Crawler_reclaimed) for key, value := range s.Commands { dict[key] = tools.IntToString(int64(value)) } return dict }