Skip to content

Commit

Permalink
- Handle Ctrl+C signal to graceful shutdown
Browse files Browse the repository at this point in the history
- Update readme.md
- Implement test cases for storage
  • Loading branch information
kalpeshdeo committed Jul 18, 2023
1 parent 9dd8760 commit 086e754
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 24 deletions.
44 changes: 23 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# Key Value DB (Redis v0.0.1) in Go

This readme file provides an overview and instructions for using the keyvaluedb CLI tool written in Golang.

This repository serves as a reference implementation for the problem statement described [here](https://playbook.one2n.in/Key-Value-DB-Redis-exercise).
## Description

The CLI tool is a key-value database (KVDB) that allows users to interact with a simple in-memory database through a TCP server. It provides a command-line interface for executing various commands and retrieving results.

## Installation

To use the CLI tool, you need to have Golang(1.18) installed on your machine. Follow the steps below to install and set up the tool:
To use the CLI tool, you need to have Go(1.18) installed on your machine. Follow the steps below to install and set up the tool:

1. Clone the repository or download the source code files.
2. Open a terminal and navigate to the project directory.
Expand All @@ -26,51 +25,54 @@ To use the CLI tool, you need to have Golang(1.18) installed on your machine. Fo

To start the TCP server and use the CLI tool, follow these steps:

1. Ensure the environment variable `APP_PORT` is set to the desired port number on which the TCP server should listen. For example, you can set it to `9736` by running:

```shell
export APP_PORT=9736
```
1. Create `.env` file in the root directory and set the desired values to the below environment variables. We have provided a `.env.example` file for reference.

Replace `9736` with the desired port number.
1. Ensure the environment variable `APP_PORT` is set to the desired port number on which the TCP server should listen. For example, you can set it to `9736` by running:

2. Optionally, if you want to specify the number of in-memory databases (`DB_COUNT`), set the environment variable as well. For example:
```shell
export APP_PORT=9736
```

```shell
export DB_COUNT=16
```
Replace `9736` with the desired port number.

2. Optionally, if you want to specify the number of in-memory databases (`DB_COUNT`), set the environment variable as well. For example:

```shell
export DB_COUNT=16
```

Replace `16` with the desired number of databases. If not set, the default value is `16`.
Replace `16` with the desired number of databases. If not set, the default value is `16`.

3. Run the following command to start the TCP server:
2. Run the following command to start the TCP server:

```shell
./kvdb
```

Replace `./kvdb` with the actual path to the `kvdb` executable if it's not in the current directory or not in your `PATH`.
4. The TCP server will start and display a message indicating that it is listening on the specified port.
3. The TCP server will start and display a message indicating that it is listening on the specified port.
5. Open another terminal or use a tool like `nc` to connect to the TCP server. For example:
4. Open another terminal or use a tool like `nc` to connect to the TCP server. For example:
```shell
nc localhost 9736
```
Replace `localhost` with the appropriate host if the server is running on a different machine, and `9736` with the correct port number.
6. Once connected, you can start interacting with the CLI tool by entering commands. The command prompt is denoted by a `$` symbol.
5. Once connected, you can start interacting with the CLI tool by entering commands. The command prompt is denoted by a `$` symbol.
7. The available commands are case-insensitive and can be entered in the following format:
6. The available commands are case-insensitive and can be entered in the following format:
```
COMMAND [argument1] [argument2] ...
```
Replace `COMMAND` with one of the supported commands and provide the necessary arguments.
8. The CLI tool supports the following commands:
7. The CLI tool supports the following commands:
- `SET key value`: Sets the value of the specified key in the current database.
- `GET key`: Retrieves the value of the specified key from the current database.
Expand All @@ -85,9 +87,9 @@ To start the TCP server and use the CLI tool, follow these steps:
Replace key, value, index, and increment with the appropriate values.
9. After entering a command, the CLI tool will display the result of the command. If the result is a list, each item will be numbered.
8. After entering a command, the CLI tool will display the result of the command. If the result is a list, each item will be numbered.
10. To exit the CLI tool, close the `nc` connection or terminate the terminal session.
9. To exit the CLI tool, close the `nc` connection or terminate the terminal session.
## Dependencies
Expand Down
6 changes: 3 additions & 3 deletions domain/keyvaluedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ func NewKeyValueDB(storage storage.Storage) KeyValueDB {
func (kvdb *KeyValueDB) Execute(dbIndex int, cmd Command) (int, interface{}) {
_, err := cmd.Validate()
if err != nil {
return 0, err.Error()
return dbIndex, err.Error()
}

if kvdb.isMultiBlockStarted && !cmd.isTerminatorCmd() {
kvdb.enqueue(cmd)
return 0, "QUEUED"
return dbIndex, "QUEUED"
}

switch cmd.Name {
case SELECT:
dbIndex, err = kvdb.storage.Select(cmd.Key)
if err != nil {
return 0, err.Error()
return dbIndex, err.Error()
}
return dbIndex, "OK"
case MULTI:
Expand Down
19 changes: 19 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ import (
"log"
"net"
"os"
"os/signal"
"strings"
"syscall"

"github.com/joho/godotenv"
)

func main() {

// Handle interrupt signal
handleInterruptSignal()

err := godotenv.Load()
if err != nil {
log.Fatal(err.Error())
Expand Down Expand Up @@ -42,6 +48,19 @@ func main() {
}
}

func handleInterruptSignal() {
// Create an interrupt channel to listen for the interrupt signal
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)

go func() {
<-interrupt
fmt.Println("Interrupt signal received. Gracefully stopping...")

os.Exit(0)
}()
}

func startTcpServer(port string) (net.Listener, error) {
listener, err := net.Listen("tcp", port)
if err != nil {
Expand Down
Loading

0 comments on commit 086e754

Please sign in to comment.