Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add search fetch context #32

Merged
merged 7 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 45 additions & 15 deletions api/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 66 additions & 18 deletions api/swagger.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
openapi: 3.0.2
x-stoplight:
id: zo1541bc64oxo
id: 44w9u0405b53e
info:
title: Unconditional
version: '1.0'
version: "1.0"
servers:
- url: 'https://api.unconditional.day/v1'
- url: 'http://localhost:8080'
- url: '127.0.0.1:8080'
- url: "https://api.unconditional.day/v1"
- url: "http://localhost:8080"
- url: "127.0.0.1:8080"
paths:
"/v1/search/feed/{query}":
get:
Expand All @@ -34,8 +34,33 @@ paths:
schema:
type: string
x-stoplight:
id: pacmz9rv7a1k1
/v1/version:
id: wosl2fd4xhhrd
"/v1/search/context/{query}":
get:
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/SearchContextDetails"
"500":
description: Internal Server Error
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/Error"
parameters:
- name: query
in: path
required: true
schema:
type: string
x-stoplight:
id: idoe8qr80ebxd
"/v1/version":
get:
summary: Your GET endpoint
tags: []
Expand All @@ -45,10 +70,11 @@ paths:
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/ServerVersion"
operationId: get-v1-version
x-stoplight:
id: flrb4hew86v1s
id: q4lvzczpgn9wh
requestBody:
content:
application/json:
Expand Down Expand Up @@ -84,7 +110,7 @@ components:
- language
- date
x-stoplight:
id: r1huzg5l9oykp
id: xa4xmb6bpguaf
FeedImage:
type: object
properties:
Expand All @@ -96,7 +122,29 @@ components:
- url
- title
x-stoplight:
id: g5p7hclip2ydk
id: cmmybtqamyqiy
SearchContextDetails:
type: object
x-stoplight:
id: 2bea7d1686f73
properties:
title:
type: string
link:
type: string
summary:
type: string
thumbnail:
type: string
language:
type: string
required:
- title
- link
- summary
- thumbnail
- language
title: SearchContextDetails
Error:
type: object
properties:
Expand All @@ -108,11 +156,11 @@ components:
- message
- code
x-stoplight:
id: gdj84rexxmxft
id: ugjrjhvkdmen2
ServerVersion:
title: ServerVersion
x-stoplight:
id: z6s8y1u6qlv0p
id: 24qo1fm939bg5
type: object
properties:
source:
Expand All @@ -125,34 +173,34 @@ components:
SourceReleaseVersion:
title: SourceReleaseVersion
x-stoplight:
id: 9jgspbctklvnr
id: ufsclw4vu3qp5
type: object
properties:
version:
type: string
x-stoplight:
id: ebqolha5zfx9n
id: t6xp7ev3nprdj
lastUpdatedAt:
type: string
x-stoplight:
id: xj2nln4v17pzd
id: 26hfi8gtj9bdi
required:
- version
- lastUpdatedAt
ServerBuildVersion:
title: ServerBuildVersion
x-stoplight:
id: 7r5btva4x51y3
id: p7byzats6s3zt
type: object
properties:
commit:
type: string
x-stoplight:
id: kbcq283u8u0h0
id: eoik296b0ddt3
version:
type: string
x-stoplight:
id: sia3kpjqax11w
id: jup15zjavkg3a
required:
- commit
- version
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ module github.com/unconditionalday/server
go 1.21

require (
github.com/anaskhan96/soup v1.2.5
github.com/deepmap/oapi-codegen v1.15.0
github.com/getkin/kin-openapi v0.120.0
github.com/labstack/echo/v4 v4.11.2
github.com/labstack/gommon v0.4.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/pflag v1.0.5
go.uber.org/zap v1.26.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ github.com/SlyMarbo/rss v1.0.5 h1:DPcZ4aOXXHJ5yNLXY1q/57frIixMmAvTtLxDE3fsMEI=
github.com/SlyMarbo/rss v1.0.5/go.mod h1:w6Bhn1BZs91q4OlEnJVZEUNRJmlbFmV7BkAlgCN8ofM=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/anaskhan96/soup v1.2.5 h1:V/FHiusdTrPrdF4iA1YkVxsOpdNcgvqT1hG+YtcZ5hM=
github.com/anaskhan96/soup v1.2.5/go.mod h1:6YnEp9A2yywlYdM4EgDz9NEHclocMepEtku7wg6Cq3s=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
Expand Down
112 changes: 112 additions & 0 deletions internal/client/wikipedia/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package wikipedia

import (
"crypto/sha256"
"errors"
"time"
)

// Find and delete string s in string slice
func FindAndDel(arr []string, s string) []string {
index := 0
for i, v := range arr {
if v == s {
index = i
break
}
}
return append(arr[:index], arr[index+1:]...)
}

func MakeWikiCache(expiration time.Duration, maxMemory int) *Cache {
if expiration != 0 {
expiration = (12 * time.Hour)
}

if maxMemory != 0 {
maxMemory = 500
}

c := &Cache{
Memory: map[string]RequestResult{},
MaxMemory: maxMemory,
Expiration: expiration,
HashedKeyQueue: make([]string, 0, maxMemory),
CreatedTime: map[string]time.Time{},
}

return c
}

// Cache to store request result
type Cache struct {
Memory map[string]RequestResult // Map store request result
HashedKeyQueue []string // Key queue. Delete the first item if reach max cache
CreatedTime map[string]time.Time // Map store created time
Expiration time.Duration // Cache expiration
MaxMemory int // Max cache memory
}

// Hash a string into SHA256
func HashCacheKey(s string) string {
hasher := sha256.New()
hasher.Write([]byte(s))

return string(hasher.Sum(nil))
}

// Get Cache current number of cache
func (cache Cache) GetLen() int {
return len(cache.HashedKeyQueue)
}

// Add result into the Cache
func (cache *Cache) Add(s string, res RequestResult) {
if len(cache.Memory) >= cache.MaxMemory {
cache.Pop()
}

key := HashCacheKey(s)
if cache.Memory == nil {
cache.Memory = map[string]RequestResult{}
cache.CreatedTime = map[string]time.Time{}
cache.HashedKeyQueue = make([]string, 0, cache.MaxMemory)
}
if _, ok := cache.Memory[key]; !ok {
cache.Memory[key] = res
cache.CreatedTime[key] = time.Now()
cache.HashedKeyQueue = append(cache.HashedKeyQueue, key)
}
}

func (cache *Cache) Get(s string) (RequestResult, error) {
key := HashCacheKey(s)
if value, ok := cache.Memory[key]; ok {
if time.Since(cache.CreatedTime[key]) <= cache.Expiration {
cache.HashedKeyQueue = FindAndDel(cache.HashedKeyQueue, key)
cache.HashedKeyQueue = append(cache.HashedKeyQueue, key)
return value, nil
} else {
cache.HashedKeyQueue = FindAndDel(cache.HashedKeyQueue, key)
delete(cache.Memory, key)
return RequestResult{}, errors.New("the data is outdated")
}
}
return RequestResult{}, errors.New("cache key not exist")
}

// Delete the first key in the Cache
func (cache *Cache) Pop() {
if len(cache.HashedKeyQueue) == 0 {
return
}
delete(cache.Memory, cache.HashedKeyQueue[0])
cache.HashedKeyQueue = cache.HashedKeyQueue[1:]
}

// Clear the whole Cache
func (cache *Cache) Clear() {
*cache = Cache{}
// This line to avoid declare but not used error
_ = cache
}
Loading