Apresentará as motivações e lições aprendidas na criação de uma aplicação de larga escala orientada a serviços. Entenda como fatores como performance, estilos de comunicação e produtividade da equipe relacionam-se à estruturação de uma aplicação.
23. Doorkeeper
class
DoorkeeperWithRepresenter
include
Untied::Doorkeeper
def
initialize
watch
User,
:after_create,
represent_with:
UserRepresenter
watch
Course,
:after_create,
represent_with:
CourseRepresenter
end
end
34. Solução
• MongoDB
• Dados não estruturados
• Possibilidade de guardar estrutura de
dados complexas
• Mais facilmente escalável
• Boa biblioteca de consulta
35. Solução
• Aplicação isolada (fail-safe)
• Interação através de uma API REST
• em-http-request (requisições
assíncronas e paralelas)
36. Implementação inicial
• Cliente da API (VisClient) bem simples
• Uso do em-http-request para envio de
requisições de forma assíncrona e
paralela
• Falhas logadas em arquivos
• Uso extensivo de Observers
37. Requisições
• Assíncronas
• Logs em arquivos
def
send_async_info(params,
url)
if
EM.reactor_running?
do_request(params,
url,
true)
else
...
end
end
def
do_request(params,
url,
self_reactor)
http
=
EM::HttpRequest.new(url).post({:body
=>
params.to_json
})
http.callback
do
...
rescue
log.error
"log
goes
here..."
end
EM.stop
unless
self_reactor
end
http.errback
do
...
rescue
log.error
"log
goes
here..."
end
EM.stop
unless
self_reactor
end
end
38. Requisições
• Paralelas
• Logs em arquivos
def
send_multi_request
...
em
do
multi
=
EventMachine::MultiRequest.new
enrollments.each_with_index
do
|enroll,
idx|
multi.add
idx,
EM::HttpRequest.new(url).post({
:body
=>
enroll.to_json
})
end
multi.callback
do
multi.responses[:errback].each
do
|err|
logger.error
"logs
goes
here..."
end
EM.stop
unless
@running
end
end
end
41. Lições Aprendidas
• Não havia interface única para envio das
notificações, ou seja, código espalhado e
de difícil manutenção
• O em-http-request é construído em cima
do EventMachine
• Logar em arquivos com propósito de
recuperar falhas é uma bola de neve
42. Lições Aprendidas
• Lidar com requisições paralelas é difícil
• Pouco workers do nginx para muitas
requisições paralelas
• Difícil depuração
44. Atualmente
• Delayed Job lida com falhas e reenvios de
uma forma atômica
• VisClient responsável por criar Jobs e
construir os parâmetros
• Simples depuração e detecção de falhas
• Uso de representers
github.com/apotonick/roar
45. New vis client
• Envio de requisições
(Faraday)
• Lógica de criação de
jobs
• Lógica de
parametrização
def
self.notify_delayed(resource,
type,
args)
elements
=
args.respond_to?(:map)
?
args
:
[args]
notifier_builder
=
NotifierBuilder.new(resource,
type,
elements)
notifier_builder.build
end
46. Representer
module
Vis
module
EnrollmentVisRepresenter
include
Roar::Representer::JSON
property
:user_id
property
:subject_id
property
:space_id
property
:course_id
property
:created_at
property
:updated_at
def
space_id
self.subject.space.id
end
def
course_id
self.subject.space.course.id
end
end
end
48. Futuro
• Vis vai se tornar provedora de Relatórios e
Visualizações
• não haverá API de consulta
• relatórios e visualizações estarão em
Vis, front-end incluso
• inclusão será feita através de iframe