Redis
O AdonisJs torna muito simples trabalhar com redis. Internamente, ele faz uso do ioredis, mas a API é um pouco diferente para manter seu código sustentável e legível.
Recursos
- Suporte para múltiplas conexões redis.
- Conecte-se ao cluster redis.
- Suporte para sentinela e transações.
- Suporte extensivo para Pub/Sub.
- Amigável com geradores ES2015.
Configuração
O provedor Redis não é enviado com a instalação base do AdonisJs, o que significa que você precisa instalá-lo e configurá-lo manualmente.
# Instalando a partir do Npm
npm i --save adonis-redis
// bootstrap/app.js
const providers = [
// ...
'adonis-redis/providers/RedisFactoryProvider',
'adonis-redis/providers/RedisProvider'
// ...
]
// bootstrap/app.js
const aliases = {
// ...
Redis: 'Adonis/Addons/Redis'
// ...
}
Config
Além disso, um arquivo de configuração precisa ser salvo como config/redis.js. Você pode baixar a configuração de exemplo do github ou executar o comando bash abaixo para salvar o arquivo automaticamente.
# Baixar usando wget
wget https://raw.githubusercontent.com/adonisjs/adonis-redis/develop/examples/redis.js -O config/redis.js
Exemplo básico
Depois que tudo estiver configurado, você estará pronto para usar o Redis dentro de seus aplicativos AdonisJs. Vamos começar com um exemplo básico de cache de usuários dentro do redis.
OBSERVAÇÃO
O exemplo abaixo pode não ser a melhor maneira de armazenar usuários em cache, mas dá uma ideia de como usar o provedor redis.
// app/Http/Controllers/UsersController.js
'use strict'
const Redis = use('Redis')
const User = use('App/Model/User')
class UsersController {
* index (request, response) {
const cachedUsers = yield Redis.get('users')
if (cachedUsers) {
response.json(JSON.parse(cachedUsers))
return
}
const users = yield User.all()
yield Redis.set('users', JSON.stringify(users))
response.json(users)
}
}
Comandos Redis
Todos os comandos redis são suportados como funções javascript. Por exemplo:
'use strict'
const Redis = use('Redis')
const user = {
username: 'foo',
email: 'foo@bar.com'
}
yield Redis.hmset('users', user.username, JSON.stringify(user))
const user = yield Redis.hmget('users', user.username) // returns stringified JSON
Pub/Sub
O Redis tem suporte integrado para Pub/Sub para compartilhar mensagens no mesmo servidor ou em vários servidores. O AdonisJs oferece uma API limpa para assinar e publicar mensagens sem nenhum esforço extra.
É recomendado criar um novo arquivo dentro do diretório bootstrap para registrar assinantes.
// bootstrap/redis.js
'use strict'
const Redis = use('Redis')
Redis.subscribe('music', function * (track) {
console.log('received track', track)
})
Em seguida, você precisa exigir este arquivo dentro do arquivo bootstrap/http.js
para garantir que ele seja carregado ao inicializar o servidor HTTP logo após a declaração require('./events')
.
// bootstrap/http.js
require('./redis')
Agora, em qualquer lugar dentro do seu aplicativo, você pode publicar no canal de música e o ouvinte registrado será chamado.
// app/Http/routes.js
'use strict'
const Route = use('Route')
const Redis = use('Redis')
Route.post('musics', function * (request, response) {
Redis.publish('music', request.all())
})
Métodos Pub/Sub
Abaixo está a lista de métodos pub/sub expostos pelo Redis Provider.
subscribe(channel, listener)
----
Redis.subscribe('music', function * (track, channel) {
console.log(track)
})
Além disso, o listener
pode ser uma referência a um módulo dentro do diretório app/Listeners
.
Redis.subscribe('music', 'Music.newTrack')
// app/Listeners/Music.js
'use strict'
const Music = exports = module.exports = {}
Music.newTrack = function * (track, channel) {
console.log(track)
}
psubscribe(pattern, listener)
O método psubscribe
assinará um padrão, e mensagens correspondentes serão enviadas ao ouvinte.
Redis.psubscribe('h?llo', function * (message, channel, pattern) {
})
Redis.publish('hello')
Redis.publish('hallo')
publish
Publique mensagem em um determinado canal.
Redis.publish('music', {id: 1, title: 'Love me like you do', artist: 'Ellie goulding'})
unsubscribe(channel, [callback])
Cancelar inscrição de um determinado canal.
Redis.unsubscribe('music')
punsubscribe(pattern, [callback])
Cancelar inscrição de um determinado padrão.
Redis.punsubscribe('h?llo')
Transações
As transações são úteis quando você deseja executar operações em massa em um determinado ponto do tempo. Vamos revisar um exemplo de adição de usuários a uma lista.
'use strict'
const User = use('App/Model/User')
const Redis = use('Redis')
class UsersController {
* index (request, response) {
const users = yield User.all()
// Criando uma transação
const multi = Redis.multi()
users.each((user) => {
multi.lpush('users-list', JSON.stringify(user))
})
yield multi.exec()
response.json(users)
}
}
multi
Cria uma nova transação para chamar vários comandos e executá-los juntos.
const multi = Redis.multi()
multi
.set('foo', 'bar')
.set('bar', 'baz')
const response = yield multi.exec()
// [[null, 'OK'], [null, 'OK']]
Pipelines
Pipelines são bem parecidos com transações, mas não garantem que todos os comandos serão executados em uma transação. Pipelines são úteis para enviar um lote de comandos para economizar viagens de ida e volta na rede.
pipeline
const pipeline = Redis.pipeline()
pipeline
.set('foo', 'bar')
.set('bar', 'baz')
const response = yield pipeline.exec()
// [[null, 'OK'], [null, 'OK']]
Conexões múltiplas
Você pode definir a configuração para várias conexões dentro do arquivo config/redis.js
e pode usar essas conexões chamando o método connection
.
// config/redis.js
module.exports = {
connection: 'local',
local: {
...
},
secondary: {
host: 'myhost.com',
port: 6379
}
}
connection(name)
Alternar para uma conexão diferente.
yield Redis.connection('secondary').get('users')
quit([name])
O AdonisJs cria um pool de conexões para reutilizar a conexão estabelecida. Use o método quit
para fechar uma única/todas as conexões do redis.
const response = yield Redis.quit('secondary')
// ou
const response = yield Redis.quit() // close all connections
Eventos do ciclo de vida
Você pode registrar um ouvinte para eventos do ciclo de vida da mesma forma que faria para Pub/Sub.
// bootstrap/redis.js
'use strict'
const Redis = use('Redis')
Redis.on('connect', function () {
// ...
})
Redis.on('error', function (error) {
// ...
})
Abaixo está a lista de eventos emitidos pelo provedor Redis.
Evento | Descrição |
---|---|
connect | emite quando uma conexão é estabelecida com o servidor Redis. |
ready | emite quando CLUSTER INFO relata que o cluster é capaz de receber comandos (se enableReadyCheck=true) ou imediatamente após o evento connect (se enableReadyCheck=false). |
error | emite quando ocorre um erro ao conectar com uma propriedade de lastNodeError representando o último erro de nó recebido. Este evento é emitido silenciosamente (emitindo somente se houver pelo menos um ouvinte). |
close | emite quando uma conexão estabelecida do servidor Redis é fechada. |
reconnecting | emite após close quando uma reconexão será feita. O argumento do evento é o tempo (em ms) antes da reconexão. |
end | emite após close quando nenhuma outra reconexão será feita. |
+node | emite quando um novo nó é conectado. |
-node | emite quando um nó é desconectado. |
node error | emite quando ocorre um erro ao conectar a um nó |