Skip to content

Commit

Permalink
v1.1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
zero734kr committed Jul 29, 2020
1 parent 4557918 commit 683742d
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 119 deletions.
53 changes: 37 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,52 @@ npm install koreanbots

### Koreanbots.MyBot

| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|--------------------------|-------------|-----|------------|---------------------------------------------------------------------------|
| `token` | String | O | - | Koreanbots의 토큰 |
| `options.noWarning` | Boolean | | false | 모듈의 경고 알림을 끕니다 |
| `options.avoidRateLimit` | Boolean | | true | 레이트리밋을 최대한 피합니다 |
| `options.GCFlushOnMB` | Number | | 5 | 캐시 값 용량이 ${옵션의 숫자}MB가 될시 캐시를 초기화합니다 |
| `options.GCInterval` | Number(ms) | | 216000000 | `options.GCInterval` 밀리초마다 `options.GCFlushOnMB`MB를 넘을시 캐시를 초기화합니다 |
| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|-----------------------------|-------------|-----|------------|----------------------------------------------------------------------------|
| `token` | String | O | - | Koreanbots의 토큰 |
| `options.noWarning` | Boolean | | false | 모듈의 경고 알림을 끕니다 |
| `options.avoidRateLimit` | Boolean | | true | 레이트리밋을 최대한 피합니다 |
| `options.autoFlush` | Number | | 100 | 캐시에 저장된 데이터 수가 `options.autoFlush`를 넘을시 캐시를 초기화합니다. (자동 캐시 관리) |
| `options.autoFlushInterval` | Number | | 3600000 | `options.autoFlushInterval`(밀리초)마다 캐시를 관리합니다 |

### Koreanbots.Bots

* 주의: Bots는 캐시를 자주 활용합니다. 이는 곧 메모리 사용량으로 직결되며 GC로 시작하는 옵션들을 잘 설정해주세요.
* 주의: Bots는 캐시를 자주 활용합니다. 이는 곧 메모리 사용량으로 직결되며 autoFlush로 시작하는 옵션들을 잘 설정해주세요.

| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|--------------------------|-------------|-----|------------|---------------------------------------------------------------------------|
| `options.noWarning` | Boolean | | false | 모듈의 경고 알림을 끕니다 |
| `options.avoidRateLimit` | Boolean | | true | 레이트리밋을 최대한 피합니다 |
| `options.GCFlushOnMB` | Number | | 5 | 캐시 값 용량이 ${옵션의 숫자}MB가 될시 캐시를 초기화합니다 |
| `options.GCInterval` | Number(ms) | | 216000000 | `options.GCInterval` 밀리초마다 `options.GCFlushOnMB`MB를 넘을시 캐시를 초기화합니다 |
| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|-----------------------------|-------------|-----|------------|----------------------------------------------------------------------------|
| `options.noWarning` | Boolean | | false | 모듈의 경고 알림을 끕니다 |
| `options.avoidRateLimit` | Boolean | | true | 레이트리밋을 최대한 피합니다 |
| `options.autoFlush` | Number | | 100 | 캐시에 저장된 데이터 수가 `options.autoFlush`를 넘을시 캐시를 초기화합니다. (자동 캐시 관리) |
| `options.autoFlushInterval` | Number | | 3600000 | `options.autoFlushInterval`(밀리초)마다 캐시를 관리합니다 |

### Koreanbots.Widgets

| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|-----------------------------|-------------|-----|------------|----------------------------------------------------------------------------|
| `options.autoFlush` | Number | | 100 | 캐시에 저장된 데이터 수가 `options.autoFlush`를 넘을시 캐시를 초기화합니다. (자동 캐시 관리) |
| `options.autoFlushInterval` | Number | | 3600000 | `options.autoFlushInterval`(밀리초)마다 캐시를 관리합니다 |

## 수동 메모리(캐시) 관리

```js
const { SearchCache } = require("koreanbots")._cache.Bots

if(SearchCache.getStats().vsize >= 10 * 1024 * 1024) SearchCache.flushAll()
if(SearchCache.size >= 100) SearchCache.clear()
```

### 위젯

```js
const { Widgets } = require("koreanbots")
const widget = new Widgets()
const { MessageAttachment } = require("discord.js")

widget.getVoteWidget(client.user.id, "jpeg").then(w => {
let wg = new MessageAttachment(w)

message.channel.send(wg)
}).catch(er => { throw er })
```

## 테스트하기
Expand Down Expand Up @@ -125,7 +146,7 @@ client.login("토큰")

- 아이디로 봇 정보 가져오기 (/bots/get/:id)
```js
const koreanbots = require('koreanbots');
const koreanbots = require("koreanbots");
const Bots = new koreanbots.Bots()

Bots.get("653534001742741552")
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koreanbots",
"version": "1.1.4",
"version": "1.1.5",
"description": "JS SDK for Koreanbots",
"main": "src/index.js",
"scripts": {
Expand All @@ -27,9 +27,10 @@
},
"license": "MIT",
"dependencies": {
"@discordjs/collection": "^0.1.6",
"discord.js": "^12.2.0",
"node-cache": "^5.1.2",
"node-fetch": "^2.6.0"
"node-fetch": "^2.6.0",
"sharp": "^0.25.4"
},
"devDependencies": {
"eslint": "^7.1.0"
Expand Down
64 changes: 23 additions & 41 deletions src/bots.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,27 @@ class Bots {
this.options = options
this.options.noWarning = options.noWarning === true
this.options.avoidRateLimit = options.avoidRateLimit === undefined ? true : options.avoidRateLimit === true
this.options.GCFlushOnMB = options.GCFlushOnMB || 5
this.options.GCInterval = options.GCInterval || 60000 * 60 * 60
this.options.autoFlush = options.autoFlush || 100
this.options.autoFlushInterval = options.autoFlushInterval || 60000 * 60

this.cache = BotsCache
this.remainingPerEndpointCache = BotsdotjsRemainingPerEndpoint
this._privateCache = {
search: SearchCache, category: CategoryCache
}

setInterval(() => {
let cacheValueMB = this.cache.stats.vsize / 1024 / 1024
let remainingPerEndpointCacheValueMB = this.remainingPerEndpointCache.stats.vsize / 1024 / 1024
let searchValueMB = this.privateCache.search.stats.vsize / 1024 / 1024
let categoryValueMB = this.privateCache.category.stats.vsize / 1024 / 1024

function flush(cache) {
cache.flushAll()
if (!this.options.noWarning) process.emitWarning("Koreanbots cache flushed by Koreanbots GC, because this cache exceeded 10MB of size.", "KoreanbotsGCWarning")
}

if (cacheValueMB > this.options.GCFlushOnMB) flush(this.cache)
if (remainingPerEndpointCacheValueMB > this.options.GCFlushOnMB) flush(this.remainingPerEndpointCache)
if (searchValueMB > this.options.GCFlushOnMB) flush(this.privateCache.search)
if (categoryValueMB > this.options.GCFlushOnMB) flush(this.privateCache.category)
}, this.options.GCInterval)
if (this.options.autoFlushInterval && this.options.autoFlushInterval > 10000) {
setInterval(() => {
function flush(cache) {
if (cache.size >= this.options.autoFlush) cache.clear()
}

[
this.cache, this.remainingPerEndpointCache,
this._privateCache.search, this._privateCache.category
].map(c => flush(c))
}, this.options.autoFlushInterval)
}
}

/**
Expand Down Expand Up @@ -74,7 +70,7 @@ class Bots {
if (r.status === 429 || data === { size: 0, timeout: 0 }) {
if (!this.options.noWarning) process.emitWarning(`Rate limited from ${r.url}`, "RateLimitWarning")

if (this.cache[endpoint] && opt.method !== "POST") return this.cache.get(endpoint)
if (this.cache.get(endpoint) && opt.method !== "POST") return this.cache.get(endpoint)

return {
code: 429,
Expand All @@ -83,37 +79,23 @@ class Bots {
}

if (r.status === 200 && opt.disableGlobalCache !== true) {
if (this.cache.has(endpoint)) this.cache.del(endpoint)
if (this.cache.has(endpoint)) this.cache.delete(endpoint)

data["updatedTimestamp"] = Date.now()

try {
this.cache.set(endpoint, data)
} catch (err) {
if (String(err).includes("ECACHEFULL")) {
this.cache.flushAll()
this.cache.set(endpoint, data)
}
}
this.cache.set(endpoint, data)
}
if (r.status === 200) {
if (this.remainingPerEndpointCache.has(endpoint)) this.remainingPerEndpointCache.del(endpoint)

try {
this.remainingPerEndpointCache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
} catch (err) {
if (String(err).includes("ECACHEFULL")) {
this.remainingPerEndpointCache.flushAll()
this.cache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
}
}
if (this.remainingPerEndpointCache.has(endpoint)) this.remainingPerEndpointCache.delete(endpoint)

this.remainingPerEndpointCache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
}
if (r.status.toString().startsWith("4") || r.status.toString().startsWith("5")) throw new Error(data.message || JSON.stringify(data))

return data
})
.catch(e => {
if (String(e).includes("body used already") && opt.method !== "POST") return this.cache[endpoint]
if (String(e).includes("body used already") && opt.method !== "POST") return this.cache.get(endpoint)

throw e
})
Expand Down Expand Up @@ -163,7 +145,7 @@ class Bots {
})

setTimeout(() => {
if (this._privateCache.search.has(`${query}/${page}`)) this._privateCache.search.del(`${query}/${page}`)
if (this._privateCache.search.has(`${query}/${page}`)) this._privateCache.search.delete(`${query}/${page}`)
}, 60000 * 30)
this._privateCache.search.set(`${query}/${page}`, res)
return res
Expand Down Expand Up @@ -208,7 +190,7 @@ class Bots {
})

setTimeout(() => {
if (this._privateCache.category.has(`${category}/${page}`)) this._privateCache.category.del(`${category}/${page}`)
if (this._privateCache.category.has(`${category}/${page}`)) this._privateCache.category.delete(`${category}/${page}`)
}, 60000 * 30)
this._privateCache.category.set(`${category}/${page}`, res)
return res
Expand Down
38 changes: 11 additions & 27 deletions src/cache.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
const options = {
maxKeys: 10,
stdTTL: 60000 * 10
}

const NodeCache = require("node-cache")
const RemainingEndpointCache = new NodeCache(options)
const KoreanbotsCache = new NodeCache(options)

const botsdotjsOptions = {
maxKeys: 10,
stdTTL: 60000 * 5
}

const queryCacheOptions = {
maxKeys: 25,
stdTTL: 60000 * 5
}

const BotsCache = new NodeCache(botsdotjsOptions)
const BotsdotjsRemainingPerEndpoint = new NodeCache({
maxKeys: 10,
stdTTL: 60000 * 60
})
const SearchCache = new NodeCache(queryCacheOptions)
const CategoryCache = new NodeCache(queryCacheOptions)
const { Collection } = require("@discordjs/collection")
const RemainingEndpointCache = new Collection()
const KoreanbotsCache = new Collection()
const BotsCache = new Collection()
const BotsdotjsRemainingPerEndpoint = new Collection()
const SearchCache = new Collection()
const CategoryCache = new Collection()
const WidgetsCache = new Collection()

module.exports = {
"index.js": {
KoreanbotsCache, RemainingEndpointCache
},
"bots.js": {
BotsCache, BotsdotjsRemainingPerEndpoint, SearchCache, CategoryCache
},
"widget.js": {
WidgetsCache
}
}

//내가 봐도 이건 좀 개판이네

This comment has been minimized.

Copy link
@turtle85917

turtle85917 Jul 29, 2020

이거 뭐죠

56 changes: 24 additions & 32 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const req = require("node-fetch")
const Bots = require("./bots")
const KoreanbotsClient = require("./KoreanbotsClient")
const KoreanbotsWidgets = require("./widget")
const { KoreanbotsCache, RemainingEndpointCache } = require("./cache")["index.js"]

class MyBot {
Expand All @@ -11,28 +12,24 @@ class MyBot {
this.options = options
this.options.noWarning = options.noWarning === true
this.options.avoidRateLimit = options.avoidRateLimit === undefined ? true : options.avoidRateLimit === true
this.options.GCFlushOnMB = options.GCFlushOnMB || 5
this.options.GCInterval = options.GCInterval || 60000 * 60 * 60
this.options.autoFlush = options.autoFlush || 100
this.options.autoFlushInterval = options.autoFlushInterval || 60000 * 60

this.updatedAt = null
this.updatedTimestamp = null

this.cache = KoreanbotsCache
this.remainingPerEndpointCache = RemainingEndpointCache

if (this.options.autoFlushInterval && this.options.autoFlushInterval > 10000) {
setInterval(() => {
function flush(cache) {
if (cache.size >= this.options.autoFlush) cache.clear()
}

setInterval(() => {
let cacheValueMB = this.cache.stats.vsize / 1024 / 1024
let remainingPerEndpointCacheValueMB = this.remainingPerEndpointCache.stats.vsize / 1024 / 1024

function flush(cache) {
cache.flushAll()
if(!this.options.noWarning) process.emitWarning("Koreanbots cache flushed by Koreanbots GC, because this cache exceeded 10MB of size.", "KoreanbotsGCWarning")
}

if(cacheValueMB > this.options.GCFlushOnMB) flush(this.cache)
if (remainingPerEndpointCacheValueMB > this.options.GCFlushOnMB) flush(this.remainingPerEndpointCache)
}, this.options.GCInterval)
[this.cache, this.remainingPerEndpointCache].map(c => flush(c))
}, this.options.autoFlushInterval)
}
}

/**
Expand Down Expand Up @@ -90,30 +87,23 @@ class MyBot {
}

if (r.status === 200) {
if (this.cache.has(endpoint)) this.cache.del(endpoint)
if (this.cache.has(endpoint)) this.cache.delete(endpoint)

data["updatedTimestamp"] = Date.now()

try {
this.cache.set(endpoint, data)
} catch (err) {
if (String(err).includes("ECACHEFULL")) {
this.cache.flushAll()
this.cache.clear()
this.cache.set(endpoint, data)
}
}
}
if (r.status === 200) {
if (this.remainingPerEndpointCache.has(endpoint)) this.remainingPerEndpointCache.del(endpoint)
if (this.remainingPerEndpointCache.has(endpoint)) this.remainingPerEndpointCache.delete(endpoint)

try {
this.remainingPerEndpointCache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
} catch (err) {
if(String(err).includes("ECACHEFULL")) {
this.remainingPerEndpointCache.flushAll()
this.cache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
}
}
this.remainingPerEndpointCache.set(endpoint, r.headers.get("x-ratelimit-remaining"))
}
if (r.status.toString().startsWith("4") || r.status.toString().startsWith("5")) throw new Error(data.message || JSON.stringify(data))

Expand Down Expand Up @@ -161,7 +151,7 @@ class MyBot {
async checkVote(id) {
if (!id || typeof id !== "string") throw new Error("아이디가 주어지지 않았거나, 올바르지 않은 아이디입니다!")

if (this.cache[id]) return this.cache[id]
if (this.cache.get(id)) return this.cache.get(id)

const res = await this._fetch(`/bots/voted/${id}`, {
method: "GET",
Expand All @@ -173,16 +163,18 @@ class MyBot {
if (res.code !== 200) throw new Error(typeof res.message === "string" ? res.message : `올바르지 않은 응답이 반환되었습니다.\n응답: ${JSON.stringify(res)}`)

setTimeout(() => {
if (this.cache[id]) delete this.cache[id]
if (this.cache.has(id)) this.cache.delete[id]
}, 60000 * 60 * 6)
this.cache[id] = res
this.cache.set(id, res)
return res
}
}

let cache = require("./cache")

module.exports = { MyBot, Bots, KoreanbotsClient, _cache: {
MyBot: cache["index.js"],
Bots: cache["bots.js"]
}}
module.exports = {
MyBot, Bots, KoreanbotsClient, _cache: {
MyBot: cache["index.js"],
Bots: cache["bots.js"]
}, Widgets: KoreanbotsWidgets
}
Loading

0 comments on commit 683742d

Please sign in to comment.