@leansdk/leanrc
Version:
LeanRC is a MVC framework for creating graceful applications
147 lines (116 loc) • 6.98 kB
text/coffeescript
# This file is part of LeanRC.
#
# LeanRC is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# LeanRC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with LeanRC. If not, see <https://www.gnu.org/licenses/>.
# 1. Некоторая миграция должна создать очередь, чтобы ей потом можно было пользоваться, например Resque.create(<queueName>, <concurrency>)
# адаптер для аранги реализованный в виде миксина для Resque класса спроецирует запрос с использованием /queue
# адаптер для nodejs просто сохранит эти данные в какую нибудь базу данных (чтобы в нужный момент к ним обратиться и заиспользовать)
# 2. В аранго ничего делать в этом пункте не надо, движок базы данных сам будет заниматься менеджментом очередей и будет плодить потоки выполнения. Для nodejs при старте сервера надо проинициализировать Agenda сервис - взять из базы данных сохраненные <queueName> и <concurrency> и задефайнить хендлеры - внутри хендлера из принимаемых данных надо вычленить имя запускаемого скрипта, сделать require(<scriptName>) и заэкзекютить этот скрипт передав в него все данные поступившие в хендлер. (Agenda - должен покрывать функционал аранги по менеджменту очердей.)
# 3. класс Queue будет работать аналогично Record классу - проксировать вызовы методов к Resque классу (чтобы срабатывала нужная платформозависимая логика из миксина)
# 4. для job объектов не будет отдельного класса, потому что у них не будет никаких спец-методов - т.е. они будут чистыми структурами (обычный json объект)
###
```coffee
module.exports = (Module)->
class ApplicationResque extends Module::Resque
Module::ArangoResqueMixin # в этом миксине должны быть реализованы платформозависимые методы, которые будут посылать нативные запросы к реальной базе данных
Module
return ApplicationResque.initialize()
```
```coffee
module.exports = (Module)->
{RESQUE} = Module::
class PrepareModelCommand extends Module::SimpleCommand
Module
execute: Function,
default: ->
#...
.registerProxy Module::ApplicationResque.new RESQUE,
<config key>: <config value>
#...
PrepareModelCommand.initialize()
```
###
module.exports = (Module)->
{
AnyT
FuncG, SubsetG, MaybeG, UnionG, ListG
QueueInterface, ResqueInterface
CoreObject
} = Module::
class Queue extends CoreObject
QueueInterface
Module
# конструктор принимает второй аргумент, ссылку на resque proxy.
resque: ResqueInterface
name: String
concurrency: Number
delay: FuncG([String, AnyT, MaybeG Number], UnionG String, Number),
default: (scriptName, data, delayUntil)->
return yield .delay , scriptName, data, delayUntil
push: FuncG([String, AnyT, MaybeG Number], UnionG String, Number),
default: (scriptName, data, delayUntil)->
return yield .pushJob , scriptName, data, delayUntil
get: FuncG([UnionG String, Number], MaybeG Object),
default: (jobId)->
return yield .getJob , jobId
delete: FuncG([UnionG String, Number], Boolean),
default: (jobId)->
return yield .deleteJob , jobId
abort: FuncG([UnionG String, Number]),
default: (jobId)->
yield .abortJob , jobId
yield return
all: FuncG([MaybeG String], ListG Object),
default: (scriptName)->
return yield .allJobs , scriptName
pending: FuncG([MaybeG String], ListG Object),
default: (scriptName)->
return yield .pendingJobs , scriptName
progress: FuncG([MaybeG String], ListG Object),
default: (scriptName)->
return yield .progressJobs , scriptName
completed: FuncG([MaybeG String], ListG Object),
default: (scriptName)->
return yield .completedJobs , scriptName
failed: FuncG([MaybeG String], ListG Object),
default: (scriptName)->
return yield .failedJobs , scriptName
restoreObject: FuncG([SubsetG(Module), Object], QueueInterface),
default: (Module, replica)->
if replica?.class is and replica?.type is 'instance'
Facade = Module::ApplicationFacade ? Module::Facade
facade = Facade.getInstance replica.multitonKey
resque = facade.retrieveProxy replica.resqueName
instance = yield resque.get replica.name
yield return instance
else
return yield Module, replica
replicateObject: FuncG(QueueInterface, Object),
default: (instance)->
replica = yield instance
ipsMultitonKey = Symbol.for '~multitonKey'
replica.multitonKey = instance.resque[ipsMultitonKey]
replica.resqueName = instance.resque.getProxyName()
replica.name = instance.name
yield return replica
init: FuncG([Object, ResqueInterface]),
default: (aoProperties, aoResque) ->
arguments...
= aoResque
for own vsAttrName, voAttrValue of aoProperties
@[vsAttrName] = voAttrValue
return