Skip to content

Commit

Permalink
Add cache for abbreviated city names (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
krisukox authored Jul 21, 2023
1 parent 3a2ff2b commit 83c201a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 18 deletions.
6 changes: 6 additions & 0 deletions flights/city.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func decodeInnerObject(body *bufio.Reader) ([][][][]interface{}, error) {
}

func (s *Session) AbbrCity(city string, lang language.Tag) (string, error) {
if abbrCity, ok := s.Cities.Load(city); ok {
return abbrCity, nil
}

resp, err := s.doRequestCity(city, lang)
if err != nil {
return "", err
Expand Down Expand Up @@ -95,6 +99,8 @@ func (s *Session) AbbrCity(city string, lang language.Tag) (string, error) {
return "", fmt.Errorf("the requested city name didn't match the found. requested: %s found: %s", city, foundCity)
}

s.Cities.Store(city, serializedCity)

return serializedCity, nil
}

Expand Down
37 changes: 22 additions & 15 deletions flights/city_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,34 @@ func TestAbbrCity(t *testing.T) {
"testdata/city_athens.resp",
"testdata/city_warsaw.resp",
)
if err != nil {
t.Fatal(err)
}

session := &Session{
httpClientMock,
client: httpClientMock,
}

cityA := "Athens"
cityB := "Warsaw"

a, err := session.AbbrCity(cityA, language.English)
if err != nil {
t.Fatal(err)
}
if a != abbrA {
t.Fatalf("wrong abbreviated city name, expected: %s received: %s", abbrA, a)
}

b, err := session.AbbrCity(cityB, language.English)
if err != nil {
t.Fatal(err)
}
if b != abbrB {
t.Fatalf("wrong abbreviated city name, expected: %s received: %s", abbrB, b)
// Since httpClientMock has only two responses, run it twice to check whether
// the cache for abbreviated city names works properly
for i := 0; i < 2; i++ {
a, err := session.AbbrCity(cityA, language.English)
if err != nil {
t.Fatal(err)
}
if a != abbrA {
t.Fatalf("wrong abbreviated city name, expected: %s received: %s", abbrA, a)
}

b, err := session.AbbrCity(cityB, language.English)
if err != nil {
t.Fatal(err)
}
if b != abbrB {
t.Fatalf("wrong abbreviated city name, expected: %s received: %s", abbrB, b)
}
}
}
2 changes: 1 addition & 1 deletion flights/price_graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestGetPriceGraph(t *testing.T) {
)

session := &Session{
httpClientMock,
client: httpClientMock,
}

offers, err := session.GetPriceGraph(time.Now().AddDate(0, 0, 2), time.Now().AddDate(0, 0, 5), 0, "Athens", "Warsaw", currency.PLN, language.English)
Expand Down
22 changes: 20 additions & 2 deletions flights/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,37 @@ package flights

import (
"net/http"
"sync"
"time"
)

type Client interface {
type Map[K comparable, V any] struct {
m sync.Map
}

func (m *Map[K, V]) Load(key K) (value V, ok bool) {
v, ok := m.m.Load(key)
if !ok {
return value, ok
}
return v.(V), ok
}

func (m *Map[K, V]) Store(key K, value V) { m.m.Store(key, value) }

type HttpClient interface {
Do(req *http.Request) (*http.Response, error)
}

type Session struct {
client Client
Cities Map[string, string]

client HttpClient
}

func New() *Session {
return &Session{
Cities: Map[string, string]{},
client: &http.Client{
Timeout: 30 * time.Second,
},
Expand Down

0 comments on commit 83c201a

Please sign in to comment.