Skip to content
This repository has been archived by the owner on Jun 15, 2022. It is now read-only.

Commit

Permalink
Add time interval for saving data periodically
Browse files Browse the repository at this point in the history
* Time interval for saving data periodically feature implemented by using ticker and goroutine.
* Functions that was affected due to adding parameters to functions refactored.
* Lock-Unlock calling changed in functions.
* README and example codes updated.
  • Loading branch information
gozeloglu committed Oct 16, 2021
1 parent 9f09412 commit 84c03bb
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 71 deletions.
60 changes: 31 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,31 @@ If you want to use in your code as a package, you can call `Get` and `Set` metho
package main

import (
"fmt"
"github.com/gozeloglu/kvs"
"log"
"fmt"
"github.com/gozeloglu/kvs"
"log"
"time"
)

func main() {
db, err := kvs.Open("", "users")
if err != nil {
log.Fatalf(err.Error())
}
db.Set("john", "23")
db.Set("jack", "43")
john := db.Get("john")
fmt.Println(john)
jack := db.Get("jack")
fmt.Println(jack)
err = db.Close() // Call while closing the database.
if err != nil {
log.Fatalf(err.Error())
}
db, err := kvs.Open("", "users", 2*time.Minute)
if err != nil {
log.Fatalf(err.Error())
}

db.Set("john", "23")
db.Set("jack", "43")

john := db.Get("john")
fmt.Println(john)

jack := db.Get("jack")
fmt.Println(jack)

err = db.Close() // Call while closing the database.
if err != nil {
log.Fatalf(err.Error())
}
}

```
Expand All @@ -50,17 +51,18 @@ If you want to use as a server, you can just call two different functions. It cr
package main

import (
"github.com/gozeloglu/kvs"
"log"
"github.com/gozeloglu/kvs"
"log"
"time"
)

func main() {
db, err := kvs.Create(":1234", "users")
if err != nil {
log.Fatalf(err.Error())
}
log.Printf("DB Created.")
db.Open()
db, err := kvs.Create(":1234", "users", 2*time.Minute)
if err != nil {
log.Fatalf(err.Error())
}
log.Printf("DB Created.")
db.Open()
}

```
Expand Down
79 changes: 59 additions & 20 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package kvs
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"sync"
"time"
)

type Kvs struct {
Expand All @@ -26,6 +28,9 @@ type Kvs struct {

// addr is the server address.
addr string

// duration stands for the time interval to save data into file periodically.
duration time.Duration
}

const (
Expand All @@ -36,7 +41,7 @@ const (
// open creates data file for newly creating database. If the database file is
// already exists, it returns error without creating anything. name indicates
// database name.
func open(name string, addr string) (*Kvs, error) {
func open(name string, addr string, duration time.Duration) (*Kvs, error) {
fullPath := baseDir + name + fileExtension

// Check database's base directory
Expand All @@ -54,22 +59,58 @@ func open(name string, addr string) (*Kvs, error) {
return nil, fmt.Errorf("database couldn't created: %s", err.Error())
}
m := make(map[string]string)
return &Kvs{
name: name + fileExtension,
dir: baseDir + name + fileExtension,
dbFile: dbFile,
kv: m,
mu: sync.Mutex{},
addr: addr,
}, nil
k := &Kvs{
name: name + fileExtension,
dir: baseDir + name + fileExtension,
dbFile: dbFile,
kv: m,
mu: sync.Mutex{},
addr: addr,
duration: duration,
}

ticker := time.NewTicker(duration)
go func() {
for {
select {
case t := <-ticker.C:
err := k.write()
if err != nil {
log.Println("Writing file failed at", t.Local())
} else {
log.Println("Data saved on the file at", t.Local())
}
}
}
}()
return k, nil
} else {
return openAndLoad(name, addr)
k, err := openAndLoad(name, addr, duration)
if err != nil {
return nil, err
}

ticker := time.NewTicker(duration)
go func() {
for {
select {
case t := <-ticker.C:
err := k.write()
if err != nil {
log.Println("Writing file failed at", t.Local())
} else {
log.Println("Data saved on the file at", t.Local())
}
}
}
}()
return k, nil
}
}

// openAndLoad opens the named database file for file operations. Also, loads
// the database file into map to in-memory operations.
func openAndLoad(dbName string, addr string) (*Kvs, error) {
func openAndLoad(dbName string, addr string, duration time.Duration) (*Kvs, error) {
mu := sync.Mutex{}
mu.Lock()
defer mu.Unlock()
Expand All @@ -79,11 +120,12 @@ func openAndLoad(dbName string, addr string) (*Kvs, error) {
return nil, err
}
k := &Kvs{
name: dbName,
dir: fullPath,
dbFile: dbFile,
mu: sync.Mutex{},
addr: addr,
name: dbName,
dir: fullPath,
dbFile: dbFile,
mu: sync.Mutex{},
addr: addr,
duration: duration,
}
err = k.load()
if err != nil {
Expand Down Expand Up @@ -126,13 +168,10 @@ func (k *Kvs) load() error {

// write saves data into file. It writes the data in map to the file.
func (k *Kvs) write() error {
defer k.dbFile.Close()
d := ""
for key, val := range k.kv {
d += fmt.Sprintf("%s=%s\n", key, val)
}
err := k.dbFile.Close()
if err != nil {
return err
}
return ioutil.WriteFile(k.dir, []byte(d), 0666)
}
13 changes: 7 additions & 6 deletions db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package kvs
import (
"os"
"testing"
"time"
)

func TestOpen(t *testing.T) {
tmpDb, err := open(t.Name(), "")
tmpDb, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand All @@ -25,7 +26,7 @@ func TestOpen(t *testing.T) {
}

func TestOpenExistsFile(t *testing.T) {
tmpDb, err := open(t.Name(), "")
tmpDb, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand All @@ -38,7 +39,7 @@ func TestOpenExistsFile(t *testing.T) {
}
t.Logf("TmpDb created: %s", t.Name())

tmpDb2, err := open(t.Name(), "")
tmpDb2, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf("It should not be nil.")
}
Expand All @@ -55,7 +56,7 @@ func TestOpenExistsFile(t *testing.T) {
}

func TestKvs_Close(t *testing.T) {
db, err := open(t.Name(), "")
db, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand All @@ -75,7 +76,7 @@ func TestKvs_Close(t *testing.T) {
}

func TestWrite(t *testing.T) {
db, err := open(t.Name(), "")
db, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand Down Expand Up @@ -104,7 +105,7 @@ func TestWrite(t *testing.T) {
}

func TestLoad(t *testing.T) {
db, err := open(t.Name(), "")
db, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand Down
3 changes: 2 additions & 1 deletion example/pkg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"fmt"
"github.com/gozeloglu/kvs"
"log"
"time"
)

func main() {
db, err := kvs.Create(":1234", "users")
db, err := kvs.Create(":1234", "users", 1*time.Minute)
if err != nil {
log.Fatalf(err.Error())
}
Expand Down
3 changes: 2 additions & 1 deletion example/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package main
import (
"github.com/gozeloglu/kvs"
"log"
"time"
)

func main() {
db, err := kvs.Create(":1234", "users")
db, err := kvs.Create(":1234", "users", 1*time.Minute)
if err != nil {
log.Fatalf(err.Error())
}
Expand Down
5 changes: 3 additions & 2 deletions get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package kvs
import (
"os"
"testing"
"time"
)

func TestKvs_GetEmpty(t *testing.T) {
db, err := open(t.Name(), "")
db, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand All @@ -32,7 +33,7 @@ func TestKvs_GetEmpty(t *testing.T) {
}

func TestKvs_Get(t *testing.T) {
db, err := open(t.Name(), "")
db, err := open(t.Name(), "", 2*time.Minute)
if err != nil {
t.Fatalf(err.Error())
}
Expand Down
Loading

0 comments on commit 84c03bb

Please sign in to comment.