new CriticalSection(name)
Permite serializar a execução de trechos de códigos, impedindo assim a execução simultânea dele por mais de uma thread de execução.
O isolamento de memória entre runtimes e ambientes JavaScript já garante que não haja acesso simultâneo a objetos e variáveis. No entanto, recursos externos como arquivos, bancos de dados IDO locais e outros serviços podem requerer coordenação e serialização de acesso para evitar conflitos e garantir a integridade dos dados.
Tendo em vista que instâncias de CriticalSection não são compartilhadas entre contextos
de execução, o controle de acesso a seções críticas é implementado por meio de nomes
únicos para cada sessão crítica que necessite de serialização de execução. Dessa forma, quando
um processo entra em uma seção crítica com um nome específico, ele garante que nenhum outro
processo possa acessar a mesma seção crítica até que o primeiro processo saia dela.
As seções críticas criadas por esta classe são reentrantes, portanto, se uma thread de execução já estiver dentro de uma seção crítica, ela poderá entrar novamente sem causar um bloqueio. No entanto, é importante garantir que a thread de execução saia da seção crítica o número correto de vezes para evitar bloqueios permanentes.
Seções críticas sempre devem ser utilizadas em blocos try...finally para garantir
que a thread de execução saia da seção crítica mesmo que ocorra um erro durante a execução
do código dentro dela. Também é recomendado que a seção crítica não seja pública e seu
uso seja encapsulado nos módulos que necessitam de serialização de execução. Exemplo de
seção crítica encapsulada em um módulo:
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js');
const criticalSection = new CriticalSection('MyUniqueClassName');
function MyClass() {
}
MyClass.prototype.mySynchronizedMethod = function () {
criticalSection.enter();
try {
// Código que deve ser executado de forma serializada
} finally {
criticalSection.leave();
}
}
module.exports = MyClass;
Por conveniência, também é possível utilizar os métodos estáticos da classe CriticalSection
para entrar e sair de seções críticas sem a necessidade de criar uma instância, sendo úteis
em cenários onde a seção crítica é utilizada de forma pontual e não há necessidade de manter uma
instância dedicada para isso. Exemplo de uso dos métodos estáticos:
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js');
CriticalSection.enter('uniqueCriticalSectionName');
try {
// Código que deve ser executado de forma serializada
} finally {
CriticalSection.leave('uniqueCriticalSectionName');
}
Importante: a partir do Engine 84 é recomendado que instâncias de CriticalSection sejam
criadas diretamente por meio do construtor informando o nome da seção crítica. Opcionalmente,
também podem ser utilizadas as versões estáticas dos métodos enter, tryEnter e leave.
Para fins de compatibilidade, é mantida como variável global uma instância compartilhada
de CriticalSection cujos métodos enter e leave recebem o nome da seção crítica
como primeiro parâmetro, de forma similar aos métodos estáticos. No entanto, essa
instância compartilhada é considerada obsoleta e seu uso não é mais recomendado. Exemplo
de uso da instância compartilhada (não recomendado):
criticalSection.enter('uniqueCriticalSectionName');
try {
// Código que deve ser executado de forma serializada
} finally {
criticalSection.leave('uniqueCriticalSectionName');
}
Parameters:
| Name | Type | Description |
|---|---|---|
name |
string | Nome único da seção crítica. |
Methods
-
<static> enter(sectionName [, timeout])
-
Entra em uma seção crítica, bloqueando o acesso simultâneo a ela por outras threads de execução. Opcionalmente, é possível definir um tempo máximo de espera para o acesso à seção crítica. Será gerado um erro caso o tempo seja excedido. Se não for informado ou se for informado zero, a thread de execução aguardará indefinidamente.
Parameters:
Name Type Argument Description sectionNamestring Nome único da seção crítica.
timeoutnumber <optional>
Tempo máximo em milissegundos que o processo ficará bloqueado aguardando o acesso à seção crítica. Caso não seja informado ou se for informado o valor zero, a thread de execução aguardará indefinidamente.
Example
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js'); CriticalSection.enter('uniqueCriticalSectionName'); try { // Código que deve ser executado de forma serializada } finally { CriticalSection.leave('uniqueCriticalSectionName'); } -
<static> getInstance()
-
Obtém uma instância compartilhada desta classe.
Importante: a partir do Engine 84 é recomendado que instâncias de
CriticalSectionsejam criadas diretamente por meio do construtor informando o nome da seção crítica. Opcionalmente, também podem ser utilizadas as versões estáticas dos métodosenter,tryEntereleave.- Deprecated:
-
- Yes
Returns:
- Type
- CriticalSection
-
<static> leave(sectionName)
-
Sai de uma seção crítica, liberando o acesso para outras threads de execução. É gerado um erro se a thread de execução não estiver atualmente dentro da seção crítica, ou se a seção crítica não tiver sido adquirida com sucesso.
Parameters:
Name Type Description sectionNamestring Nome único da seção crítica.
Example
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js'); CriticalSection.enter('uniqueCriticalSectionName'); try { // Código que deve ser executado de forma serializada } finally { CriticalSection.leave('uniqueCriticalSectionName'); } -
<static> tryEnter(sectionName [, timeout])
-
Tenta entrar em uma seção crítica no tempo especificado, bloqueando o acesso simultâneo a ela por outras threads de execução caso tenha sucesso. Retorna
truese a seção crítica foi adquirida com sucesso, oufalsecaso o tempo limite tenha sido excedido.Parameters:
Name Type Argument Description sectionNamestring Nome único da seção crítica.
timeoutnumber <optional>
Tempo máximo em milissegundos que o processo ficará bloqueado aguardando o acesso à seção crítica. Caso não seja informado, será retornado imediatamente.
Returns:
Retorna
truese a seção crítica foi adquirida com sucesso, oufalsecaso o tempo limite tenha sido excedido.- Type
- boolean
-
enter( [timeout])
-
Entra em uma seção crítica, bloqueando o acesso simultâneo a ela por outras threads de execução. Opcionalmente, é possível definir um tempo máximo de espera para o acesso à seção crítica. Será gerado um erro caso o tempo seja excedido. Se não for informado ou se for informado zero, a thread de execução aguardará indefinidamente.
Parameters:
Name Type Argument Description timeoutnumber <optional>
Tempo máximo em milissegundos que o processo ficará bloqueado aguardando o acesso à seção crítica. Caso não seja informado ou se for informado o valor zero, a thread de execução aguardará indefinidamente.
Example
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js'); const criticalSection = new CriticalSection('uniqueCriticalSectionName'); criticalSection.enter(); try { // Código que deve ser executado de forma serializada } finally { criticalSection.leave(); } -
leave()
-
Sai de uma seção crítica, liberando o acesso para outras threads de execução. É gerado um erro se a thread de execução não estiver atualmente dentro da seção crítica, ou se a seção crítica não tiver sido adquirida com sucesso.
Example
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js'); const criticalSection = new CriticalSection('uniqueCriticalSectionName'); criticalSection.enter(); try { // Código que deve ser executado de forma serializada } finally { criticalSection.leave(); } -
tryEnter( [timeout])
-
Tenta entrar em uma seção crítica no tempo especificado, bloqueando o acesso simultâneo a ela por outras threads de execução caso tenha sucesso. Retorna
truese a seção crítica foi adquirida com sucesso, oufalsecaso o tempo limite tenha sido excedido.Parameters:
Name Type Argument Description timeoutnumber <optional>
Tempo máximo em milissegundos que o processo ficará bloqueado aguardando o acesso à seção crítica. Caso não seja informado, será retornado imediatamente.
Returns:
Retorna
truese a seção crítica foi adquirida com sucesso, oufalsecaso o tempo limite tenha sido excedido.- Type
- boolean
Example
const CriticalSection = require('@nginstack/engine/lib/sync/CriticalSection.js'); const criticalSection = new CriticalSection(uniqueCacheId); const acquired = criticalSection.tryEnter(5000); if (acquired) { try { if (!existsCache()) { buildCache(); } queryDataFromCache(); } finally { criticalSection.leave(); } } else { queryDataFromDatabase(); }