示例#1
0
bool Session::processRequest(StringPiece request)
{
	assert(command_.empty());
	assert(!noreply_);
	assert(policy_ == Item::kInvalid);
	assert(!currItem_);
	assert(bytesToDiscard_ == 0);
	++requestsProcessed_;

	// check 'noreply' at end of request line
	if (request.size() >= 8)
	{
		StringPiece end(request.end() - 8, 8);
		if (end == " noreply")
		{
			noreply_ = true;
			request.remove_suffix(8);
		}
	}

	SpaceSeparator sep;
	Tokenizer tok(request.begin(), request.end(), sep);
	Tokenizer::iterator beg = tok.begin();
	if (beg == tok.end())
	{
		reply("ERROR\r\n");
		return true;
	}
	(*beg).CopyToString(&command_);
	++beg;
	if (command_ == "set" || command_ == "add" || command_ == "replace"
		|| command_ == "append" || command_ == "prepend" || command_ == "cas")
	{
		// this normally returns false
		return doUpdate(beg, tok.end());
	}
	else if (command_ == "get" || command_ == "gets")
	{
		bool cas = command_ == "gets";

		// FIXME: send multiple chunks with write complete callback.
		while (beg != tok.end())
		{
			StringPiece key = *beg;
			bool good = key.size() <= kLongestKeySize;
			if (!good)
			{
				reply("CLIENT_ERROR bad command line format\r\n");
				return true;
			}

			needle_->resetKey(key);
			ConstItemPtr item = owner_->getItem(needle_);
			++beg;
			if (item)
			{
				item->output(&outputBuf_, cas);
			}
		}
		outputBuf_.append("END\r\n");

		if (conn_->outputBuffer()->writableBytes() > 65536 + outputBuf_.readableBytes())
		{
			LOG_DEBUG << "shrink output buffer from " << conn_->outputBuffer()->internalCapacity();
			conn_->outputBuffer()->shrink(65536 + outputBuf_.readableBytes());
		}

		conn_->send(&outputBuf_);
	}
	else if (command_ == "delete")
	{
		doDelete(beg, tok.end());
	}
	else if (command_ == "version")
	{
#ifdef HAVE_TCMALLOC
		reply("VERSION 0.01 muduo with tcmalloc\r\n");
#else
		reply("VERSION 0.01 muduo\r\n");
#endif
	}
#ifdef HAVE_TCMALLOC
	else if (command_ == "memstat")
	{
		char buf[1024 * 64];
		MallocExtension::instance()->GetStats(buf, sizeof buf);
		reply(buf);
	}
#endif
	else if (command_ == "quit")
	{
		conn_->shutdown();
	}
	else if (command_ == "shutdown")
	{
		// "ERROR: shutdown not enabled"
		conn_->shutdown();
		owner_->stop();
	}
	else
	{
		reply("ERROR\r\n");
		LOG_INFO << "Unknown command: " << command_;
	}
	return true;
}