Skip to content
This repository has been archived by the owner on Sep 13, 2018. It is now read-only.

Commit

Permalink
added queue. API now calls execute method
Browse files Browse the repository at this point in the history
  • Loading branch information
k-egor-smirnov committed Jan 13, 2018
1 parent 1a9c0f1 commit eb6827f
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 102 deletions.
6 changes: 3 additions & 3 deletions api-schema/utils/codeGenerate.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ function generateImports (categories) {
let code = ''

code += "const bindMethods = require('./bindMethods')\n"
code += "const request = require('./request')\n"

let categoriesName = Object.keys(categories)
categoriesName.map(categoryName => {
Expand All @@ -109,7 +108,7 @@ function generateAPIClass (categories) {
code += tab('}\n\n', 1)

// Generate init
code += tab('init () {\n', 1)
code += tab('init (queue) {\n', 1)

code += tab('for (let category of Object.keys(this)) {\n', 2)

Expand All @@ -120,13 +119,14 @@ function generateAPIClass (categories) {
code += tab('}\n', 3)

code += tab('}\n', 2)
code += tab('this.queue = queue\n', 2)

code += tab('}\n\n', 1)

// Generate API call
code += tab('_call (...params) {\n', 1)

code += tab('return request.call(this, ...params)\n', 2)
code += tab('return this.queue.add(...params)\n', 2)

code += tab('}\n', 1)

Expand Down
90 changes: 0 additions & 90 deletions lib/api/API.js

This file was deleted.

55 changes: 55 additions & 0 deletions lib/controllers/RequestController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const crypto = require('crypto')

class RequestController {
constructor (queue) {
this.queue = queue
this.callbacks = {}
}

/**
* Add request to controller
* @param {Request} request
*/
add (request) {
let id = crypto.createHmac('sha256', 'https://vk.cc/7A4bYf')
.update(request.method + Date.now() + Math.random())
.digest('hex')

request.id = id

let callback = {}

let promise = new Promise((resolve, reject) => {
callback.resolve = resolve
callback.reject = reject
})

this.callbacks[id] = callback
this.queue.requests.push(request)

return promise
}

/**
* Emits when request successed
* @param {String} id ID of request
* @param {Object} data Response data
*/
complete (id, data) {
let request = this.callbacks[id]
request.resolve(data)
}

/**
* Emits when request failed
* @param {String} id ID of request
* @param {Object} data Response data
*/
error (id, data) {
let request = this.callbacks[id]

request.reject(data)
}
}

module.exports = RequestController
23 changes: 21 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
const API = require('./api/')
const API = require('./api')

module.exports = API
class Next {
/**
* Creates an insance of VK-Next
* @param {String} token VK API token
* @param {BaseQueue} queue Queue used for requests
* @param {Boolean} isGroup Is token recieved by group
*/
constructor (token, queue, isGroup) {
this.queue = queue
this.api = new API(token)

this.queue.token = token
this.queue.isGroup = isGroup

this.queue.start()
this.api.init(this.queue)
}
}

module.exports = Next
23 changes: 23 additions & 0 deletions lib/models/Request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Request {
/**
* Create VK API requset
* @param {String} method Request method
* @param {Object} params Request params
*/
constructor (method, params = []) {
this.method = method
this.params = params
}

buildString () {
let params = []

for (let key of Object.keys(this.params)) {
params.push(`{"${key}": ${this.params[key]}}`)
}

return `API.${this.method}(${params.toString()})`
}
}

module.exports = Request
101 changes: 101 additions & 0 deletions lib/queue/BaseQueue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const RequestController = require('../controllers/RequestController')
const request = require('../utils/request')

class BaseQueue {
/**
* @param {Boolean} isGroup Is token recieved for group
*/
constructor () {
this.controller = new RequestController(this)
}

get token () {
return this._token
}

set token (token) {
this._token = token
}

get isGroup () {
return this._isGroup
}

set isGroup (isGroup) {
this._isGroup = isGroup
}

/**
* Add request to queue
*/
add () {
throw new Error('Not implemented')
}

/**
* Start processing queue
*/
start () {
throw new Error('Not implemented')
}

/**
* Stop processing queue
*/
stop () {
throw new Error('Not implemented')
}

/**
* Get chunk
*/
_getChunk () {
throw new Error('Not implemented')
}

/**
* Process a chunk
* @param {Object} chunk Array of requests
*/
async _process (chunk) {
let requests = []
chunk.map(request => {
requests.push(request.buildString())
})

let code = `return([${requests}]);`

if (requests.length > 0) {
let executeResponse = await request('execute', {
code
}, this.token)

let parsedResponse = JSON.parse(executeResponse)

if (parsedResponse['error']) {
throw new Error(parsedResponse['error']['error_msg'])
}

let responses = parsedResponse['response']
let errors = parsedResponse['execute_errors']
let errorResponses = []

for (let i in responses) {
let response = responses[i]
if (response === false) {
errorResponses.push(chunk[i].id)
} else {
this.controller.complete(chunk[i].id, response)
}
}

for (let i in errors) {
let error = errors[i]

this.controller.error(errorResponses[i], error)
}
}
}
}

module.exports = BaseQueue
33 changes: 33 additions & 0 deletions lib/queue/LocalQueue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const BaseQueue = require('./BaseQueue')
const Request = require('../models/Request')

class LocalQueue extends BaseQueue {
constructor () {
super()

this.requests = []
}

add (method, params) {
let promise = this.controller.add(new Request(method, params))

return promise
}

start () {
this.interval = setInterval(() => {
let chunk = this._getChunk()
this._process(chunk)
}, 1000 / this.isGroup ? 20 : 3)
}

stop () {
if (this.interval) clearInterval(this.interval)
}

_getChunk () {
return this.requests.splice(0, 24)
}
}

module.exports = LocalQueue
Empty file added lib/queue/RedisQueue.js
Empty file.
9 changes: 4 additions & 5 deletions lib/api/request.js → lib/utils/request.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const request = require('request-promise')
const qs = require('querystring')

/**
* Module that calls VK API
Expand All @@ -12,15 +11,15 @@ const qs = require('querystring')
module.exports = function (
method,
params = [],
v = '5.69',
access_token = this.token
access_token = this.token, // eslint-disable-line
v = '5.69'
) {
const options = {
uri: `https://api.vk.com/method/${method}`,
qs: {
access_token,
access_token, // eslint-disable-line
v,
params: qs.stringify(params)
...params
}
}

Expand Down
Loading

0 comments on commit eb6827f

Please sign in to comment.