mirror of
https://github.com/elyby/chrly.git
synced 2025-05-31 14:11:51 +05:30
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
334e60ff2f | ||
|
|
6d6d0e4b79 | ||
|
|
0cfed45b64 | ||
|
|
f872fe4698 | ||
|
|
5b4761e4e5 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -4,7 +4,16 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased] - xxxx-xx-xx
|
||||||
|
|
||||||
|
## [4.2.3] - 2019-10-03
|
||||||
|
### Changed
|
||||||
|
- Mojang's textures queue batch size [reduced to 10](https://wiki.vg/index.php?title=Mojang_API&type=revision&diff=14964&oldid=14954).
|
||||||
|
- 400 BadRequest errors from the Mojang's API are now logged.
|
||||||
|
|
||||||
|
## [4.2.2] - 2019-06-19
|
||||||
|
### Fixed
|
||||||
|
- GC for in-memory textures cache has not been initialized.
|
||||||
|
|
||||||
## [4.2.1] - 2019-05-06
|
## [4.2.1] - 2019-05-06
|
||||||
### Changed
|
### Changed
|
||||||
@@ -57,6 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
from the textures link instead.
|
from the textures link instead.
|
||||||
- `hash` field from `POST /api/skins` endpoint.
|
- `hash` field from `POST /api/skins` endpoint.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/elyby/chrly/compare/4.2.1...HEAD
|
[Unreleased]: https://github.com/elyby/chrly/compare/4.2.3...HEAD
|
||||||
|
[4.2.3]: https://github.com/elyby/chrly/compare/4.2.2...4.2.3
|
||||||
|
[4.2.2]: https://github.com/elyby/chrly/compare/4.2.1...4.2.2
|
||||||
[4.2.1]: https://github.com/elyby/chrly/compare/4.2.0...4.2.1
|
[4.2.1]: https://github.com/elyby/chrly/compare/4.2.0...4.2.1
|
||||||
[4.2.0]: https://github.com/elyby/chrly/compare/4.1.1...4.2.0
|
[4.2.0]: https://github.com/elyby/chrly/compare/4.1.1...4.2.0
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ type inMemoryTexturesStorage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateInMemoryTexturesStorage() *inMemoryTexturesStorage {
|
func CreateInMemoryTexturesStorage() *inMemoryTexturesStorage {
|
||||||
return &inMemoryTexturesStorage{
|
storage := &inMemoryTexturesStorage{
|
||||||
data: make(map[string]*inMemoryItem),
|
data: make(map[string]*inMemoryItem),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return storage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *inMemoryTexturesStorage) Start() {
|
func (s *inMemoryTexturesStorage) Start() {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (ctx *JobsQueue) queueRound() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
queueSize := ctx.queue.Size()
|
queueSize := ctx.queue.Size()
|
||||||
jobs := ctx.queue.Dequeue(100)
|
jobs := ctx.queue.Dequeue(10)
|
||||||
ctx.Logger.UpdateGauge("mojang_textures.usernames.iteration_size", int64(len(jobs)))
|
ctx.Logger.UpdateGauge("mojang_textures.usernames.iteration_size", int64(len(jobs)))
|
||||||
ctx.Logger.UpdateGauge("mojang_textures.usernames.queue_size", int64(queueSize-len(jobs)))
|
ctx.Logger.UpdateGauge("mojang_textures.usernames.queue_size", int64(queueSize-len(jobs)))
|
||||||
var usernames []string
|
var usernames []string
|
||||||
@@ -184,6 +184,12 @@ func (ctx *JobsQueue) handleResponseError(err error, threadName string) {
|
|||||||
case mojang.ResponseError:
|
case mojang.ResponseError:
|
||||||
if _, ok := err.(*mojang.TooManyRequestsError); ok {
|
if _, ok := err.(*mojang.TooManyRequestsError); ok {
|
||||||
ctx.Logger.Warning(":name: Got 429 Too Many Requests :err", wd.NameParam(threadName), wd.ErrParam(err))
|
ctx.Logger.Warning(":name: Got 429 Too Many Requests :err", wd.NameParam(threadName), wd.ErrParam(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := err.(*mojang.BadRequestError); ok {
|
||||||
|
ctx.Logger.Warning(":name: Got 400 Bad Request :err", wd.NameParam(threadName), wd.ErrParam(err))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -258,30 +258,30 @@ func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUnknownUuid
|
|||||||
suite.Assert().Nil(<-resultChan)
|
suite.Assert().Nil(<-resultChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *queueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
|
func (suite *queueTestSuite) TestReceiveTexturesForMoreThan10Usernames() {
|
||||||
usernames := make([]string, 120)
|
usernames := make([]string, 12)
|
||||||
for i := 0; i < 120; i++ {
|
for i := 0; i < cap(usernames); i++ {
|
||||||
usernames[i] = randStr(8)
|
usernames[i] = randStr(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Times(120)
|
suite.Logger.On("IncCounter", "mojang_textures.request", int64(1)).Times(12)
|
||||||
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Times(120)
|
suite.Logger.On("IncCounter", "mojang_textures.usernames.queued", int64(1)).Times(12)
|
||||||
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(100)).Once()
|
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(10)).Once()
|
||||||
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(20)).Once()
|
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.iteration_size", int64(2)).Once()
|
||||||
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(20)).Once()
|
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(2)).Once()
|
||||||
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
|
suite.Logger.On("UpdateGauge", "mojang_textures.usernames.queue_size", int64(0)).Once()
|
||||||
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything).Twice()
|
suite.Logger.On("RecordTimer", "mojang_textures.usernames.round_time", mock.Anything).Twice()
|
||||||
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_miss", int64(1)).Times(120)
|
suite.Logger.On("IncCounter", "mojang_textures.usernames.uuid_miss", int64(1)).Times(12)
|
||||||
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Times(120)
|
suite.Logger.On("RecordTimer", "mojang_textures.result_time", mock.Anything).Times(12)
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", mock.Anything).Times(120).Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", mock.Anything).Times(12).Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", mock.Anything, "").Times(120).Return(nil) // should be called with "" if username is not compared to uuid
|
suite.Storage.On("StoreUuid", mock.Anything, "").Times(12).Return(nil) // should be called with "" if username is not compared to uuid
|
||||||
// Storage.GetTextures and Storage.SetTextures shouldn't be called
|
// Storage.GetTextures and Storage.SetTextures shouldn't be called
|
||||||
|
|
||||||
suite.MojangApi.On("UsernamesToUuids", usernames[0:100]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
suite.MojangApi.On("UsernamesToUuids", usernames[0:10]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
||||||
suite.MojangApi.On("UsernamesToUuids", usernames[100:120]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
suite.MojangApi.On("UsernamesToUuids", usernames[10:12]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
||||||
|
|
||||||
channels := make([]chan *mojang.SignedTexturesResponse, 120)
|
channels := make([]chan *mojang.SignedTexturesResponse, 12)
|
||||||
for i, username := range usernames {
|
for i, username := range usernames {
|
||||||
channels[i] = suite.Queue.GetTexturesForUsername(username)
|
channels[i] = suite.Queue.GetTexturesForUsername(username)
|
||||||
}
|
}
|
||||||
@@ -417,6 +417,7 @@ func (suite *queueTestSuite) TestShouldNotLogErrorWhenExpectedErrorReturnedFromU
|
|||||||
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
|
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
|
||||||
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
|
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
|
||||||
suite.Logger.On("Debug", ":name: Got response error :err", mock.Anything, mock.Anything).Times(len(expectedErrors))
|
suite.Logger.On("Debug", ":name: Got response error :err", mock.Anything, mock.Anything).Times(len(expectedErrors))
|
||||||
|
suite.Logger.On("Warning", ":name: Got 400 Bad Request :err", mock.Anything, mock.Anything).Once()
|
||||||
suite.Logger.On("Warning", ":name: Got 429 Too Many Requests :err", mock.Anything, mock.Anything).Once()
|
suite.Logger.On("Warning", ":name: Got 429 Too Many Requests :err", mock.Anything, mock.Anything).Once()
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
|
||||||
@@ -453,6 +454,7 @@ func (suite *queueTestSuite) TestShouldNotLogErrorWhenExpectedErrorReturnedFromU
|
|||||||
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
|
suite.Logger.On("UpdateGauge", mock.Anything, mock.Anything)
|
||||||
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
|
suite.Logger.On("RecordTimer", mock.Anything, mock.Anything)
|
||||||
suite.Logger.On("Debug", ":name: Got response error :err", mock.Anything, mock.Anything).Times(len(expectedErrors))
|
suite.Logger.On("Debug", ":name: Got response error :err", mock.Anything, mock.Anything).Times(len(expectedErrors))
|
||||||
|
suite.Logger.On("Warning", ":name: Got 400 Bad Request :err", mock.Anything, mock.Anything).Once()
|
||||||
suite.Logger.On("Warning", ":name: Got 429 Too Many Requests :err", mock.Anything, mock.Anything).Once()
|
suite.Logger.On("Warning", ":name: Got 429 Too Many Requests :err", mock.Anything, mock.Anything).Once()
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Return("", &ValueNotFound{})
|
||||||
|
|||||||
@@ -51,11 +51,13 @@ var serveCmd = &cobra.Command{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texturesStorage := queue.CreateInMemoryTexturesStorage()
|
||||||
|
texturesStorage.Start()
|
||||||
mojangTexturesQueue := &queue.JobsQueue{
|
mojangTexturesQueue := &queue.JobsQueue{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
Storage: &queue.SplittedStorage{
|
Storage: &queue.SplittedStorage{
|
||||||
UuidsStorage: mojangUuidsRepository,
|
UuidsStorage: mojangUuidsRepository,
|
||||||
TexturesStorage: queue.CreateInMemoryTexturesStorage(),
|
TexturesStorage: texturesStorage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
logger.Info("Mojang's textures queue is successfully initialized")
|
logger.Info("Mojang's textures queue is successfully initialized")
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ func (cfg *Config) NotFound(response http.ResponseWriter, request *http.Request)
|
|||||||
data, _ := json.Marshal(map[string]string{
|
data, _ := json.Marshal(map[string]string{
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"message": "Not Found",
|
"message": "Not Found",
|
||||||
"link": "http://docs.ely.by/skin-system.html",
|
|
||||||
})
|
})
|
||||||
|
|
||||||
response.Header().Set("Content-Type", "application/json")
|
response.Header().Set("Content-Type", "application/json")
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ func TestConfig_NotFound(t *testing.T) {
|
|||||||
response, _ := ioutil.ReadAll(resp.Body)
|
response, _ := ioutil.ReadAll(resp.Body)
|
||||||
assert.JSONEq(`{
|
assert.JSONEq(`{
|
||||||
"status": "404",
|
"status": "404",
|
||||||
"message": "Not Found",
|
"message": "Not Found"
|
||||||
"link": "http://docs.ely.by/skin-system.html"
|
|
||||||
}`, string(response))
|
}`, string(response))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ func (cfg *Config) SignedTextures(response http.ResponseWriter, request *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
responseData.Props = append(responseData.Props, &mojang.Property{
|
responseData.Props = append(responseData.Props, &mojang.Property{
|
||||||
Name: "ely",
|
Name: "chrly",
|
||||||
Value: "but why are you asking?",
|
Value: "how do you tame a horse in Minecraft?",
|
||||||
})
|
})
|
||||||
|
|
||||||
responseJson, _ := json.Marshal(responseData)
|
responseJson, _ := json.Marshal(responseData)
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ func TestConfig_SignedTextures(t *testing.T) {
|
|||||||
"value": "mocked textures base64"
|
"value": "mocked textures base64"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ely",
|
"name": "chrly",
|
||||||
"value": "but why are you asking?"
|
"value": "how do you tame a horse in Minecraft?"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`, string(response))
|
}`, string(response))
|
||||||
@@ -132,8 +132,8 @@ func TestConfig_SignedTextures(t *testing.T) {
|
|||||||
"value": "eyJ0aW1lc3RhbXAiOjE1NTYzOTg1NzIsInByb2ZpbGVJZCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwicHJvZmlsZU5hbWUiOiJtb2NrX3VzZXIiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly9tb2phbmcvc2tpbi5wbmcifX19"
|
"value": "eyJ0aW1lc3RhbXAiOjE1NTYzOTg1NzIsInByb2ZpbGVJZCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIiwicHJvZmlsZU5hbWUiOiJtb2NrX3VzZXIiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly9tb2phbmcvc2tpbi5wbmcifX19"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ely",
|
"name": "chrly",
|
||||||
"value": "but why are you asking?"
|
"value": "how do you tame a horse in Minecraft?"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`, string(response))
|
}`, string(response))
|
||||||
|
|||||||
Reference in New Issue
Block a user