func (rs *rodisServer) Close() { log6.Info("Server is closing...") if rs.started { close(rs.quit) rs.listener.Close() for _, rc := range rs.conns { rc.close() } rs.started = false } log6.Info("Server is down.") }
func (rs *rodisServer) Run() { log6.Info("Server is starting, listen on %v", rs.cfg.Listen) listener, err := net.Listen("tcp", rs.cfg.Listen) if err != nil { log6.Fatal("Server listen on %v failure: %v", rs.cfg.Listen, err) return } rs.listener = listener rs.started = true for { conn, err := rs.listener.Accept() if err != nil { select { case <-rs.quit: return default: log6.Warn("Server accepts connection error: %v", err) } continue } go newConnection(conn, rs) } }
// strings.basic group, including set, get, getrange, setrange, append, strlen, setnx, setxx, getset func set(v resp.CommandArgs, ex *CommandExtras) error { if len(v) <= 1 { return resp.NewError(ErrFmtWrongNumberArgument, "set").WriteTo(ex.Buffer) } ex.DB.Lock() defer ex.DB.Unlock() if len(v) == 2 { if err := ex.DB.Put(v[0], v[1]); err != nil { return err } return resp.OkSimpleString.WriteTo(ex.Buffer) } option_nx := false option_xx := false expire_op := "" expire_val := int64(0) offset := 2 for offset < len(v) { option := strings.ToLower(string(v[offset])) switch option { case "xx": option_xx = true offset++ case "nx": option_nx = true offset++ case "ex", "px": if offset == len(v)-1 { // no value more return resp.NewError(ErrFmtSyntax).WriteTo(ex.Buffer) } if i, err := strconv.ParseInt(string(v[offset+1]), 10, 64); err != nil { return resp.NewError(ErrNotValidInt).WriteTo(ex.Buffer) } else { expire_op = option expire_val = i } offset += 2 default: return resp.NewError(ErrFmtSyntax).WriteTo(ex.Buffer) } } if option_nx && option_xx { return resp.NilBulkString.WriteTo(ex.Buffer) } exist := true if option_nx || option_xx { _, err := ex.DB.Get(v[0]) if err == leveldb.ErrNotFound { exist = false } } if option_nx && exist { return resp.NilBulkString.WriteTo(ex.Buffer) } if option_xx && !exist { return resp.NilBulkString.WriteTo(ex.Buffer) } if err := ex.DB.Put(v[0], v[1]); err != nil { return err } // TODO: ex/px if false { log6.Info("Set expire: %v.%v", expire_op, expire_val) } return resp.OkSimpleString.WriteTo(ex.Buffer) }