Detectar servidor ativo em Hot-Standby E3 via script.

1. Introdução

Em uma configuração de redundância (Hot-Standby), dois servidores E3 — A e B — rodam o mesmo Domínio, mas apenas um deles está ativo (Running) a cada momento; o outro fica em Standby. É comum precisar automatizar alguma rotina externa (por exemplo, um script Python em execução em cada uma das duas máquinas) que precisa descobrir localmente se o servidor daquela máquina específica é o servidor ativo agora ou não.

A forma correta de responder a essa pergunta é consultar o servidor ativo E3 via o objeto runtime [?Server], especificamente a propriedade State do servidor local. Essa verificação, no entanto, está sujeita a uma condição de conexão frequentemente negligenciada: se a conexão for estabelecida para um endereço de domínio (com failover automático) em vez do host físico local, a leitura sempre indica “ativo”, independentemente do estado real daquele servidor.

 

2. O que é o objeto [?Server]

[?Server] é um objeto runtime real (não uma macro), exposto pelo próprio E3 Server, que devolve informações sobre o servidor e sua topologia — domínio, hot-standby, sessões de clientes, licenças e domínios remotos. Os colchetes são obrigatórios, pois ? não é um caractere válido em identificadores comuns:

Application.GetObject(":[?Server]").ProductString

Dentro dele, a árvore Domain.Servers expõe o par de redundância:

  • LocalServer — sempre presente; é o servidor que está sendo acessado pela conexão atual.
  • RemoteServer — presente apenas quando HotStandby = True; é o par secundário.

Ambos expõem a propriedade State, um Long com o seguinte enum:

Valor Significado
-1 Fechado / nenhum Domínio carregado
0 Parado (carregado, mas não em execução)
1 Standby
2 Running (ativo)

3. Requisito de conexão: servidor local versus endereço de domínio

O fator determinante é para onde a conexão aponta. Se o cliente (Viewer, RemoteDomain ou uma automação externa via COM) se conecta a um endereço “de domínio” que já redireciona automaticamente para quem estiver ativo, a leitura de State quase sempre retorna 2 — porque esse tipo de conexão só consegue se conectar a servidores em execução ativa. Esse é, inclusive, o comportamento documentado da propriedade: em contextos runtime normais, Domain.State é quase sempre 2.

Para que a leitura reflita corretamente o estado daquela máquina específica (A ou B), a conexão precisa ser feita explicitamente para o servidor local daquele host — por exemplo, localhost ou o nome daquela máquina em particular — e não para um endereço com failover automático.

4. Como consultar via script (VBScript, dentro do E3)

Dentro de um script rodando no próprio E3 (por exemplo, em um evento OnStartRunning ou em um Timer), a leitura é direta:

Dim estadoLocal
estadoLocal = Application.GetObject(":[?Server].Domain.Servers.LocalServer").State

Select Case estadoLocal
    Case 2
        ' Este host é o servidor ativo agora
    Case 1
        ' Este host está em Standby
    Case 0
        ' Domínio parado
    Case -1
        ' Nenhum Domínio carregado
End Select

5. Como aplicar isso a partir de um script externo (Python)

A mesma regra vale para qualquer automação externa que se conecte ao E3 via automação COM — e não apenas para scripts internos. As bibliotecas oficiais de conexão externa da Elipse (E3DataAccess, e nas versões mais novas E3AccessLayer, usada inclusive pelo EPM para coletar dados do E3) expõem um objeto cuja propriedade Server recebe o nome do host a que conectar. Por serem bibliotecas COM padrão, qualquer linguagem com suporte a automação COM — incluindo Python, via pywin32 (win32com.client) — pode instanciá-las do mesmo jeito que uma aplicação VBA.

Procedimento recomendado, aplicado na resolução do caso que originou este artigo:

  1. No projeto local de cada servidor (A e B), um pequeno script VBScript (Timer ou OnStartRunning) grava Application.GetObject(":[?Server].Domain.Servers.LocalServer").State em uma Tag comum do projeto — por exemplo, Dados.ServidorLocalAtivo.
  2. O script Python, em execução naquela mesma máquina, conecta-se explicitamente ao servidor local (Server = "localhost" ou o nome daquele host específico — nunca o endereço de domínio/failover) e lê o valor dessa Tag pelo método GetValue da biblioteca de conexão externa.
  3. Resultado: 2 = este host é o ativo agora; 1 = este host está em Standby.
import win32com.client

e3 = win32com.client.Dispatch("E3DATAACCESSLib.E3DataAccessManager")
e3.Server = "localhost"  # host LOCAL da própria máquina — nunca o domínio/failover

estado = e3.GetValue("Dados.ServidorLocalAtivo")
# 2 = este host é o ativo agora / 1 = este host está em Standby

Requisito obrigatório, independentemente da biblioteca utilizada: a conexão (Server) deve apontar para o host físico local da máquina onde o script Python é executado, e não para um endereço de domínio com failover automático; caso contrário, os dois scripts (A e B) lerão o mesmo valor, sempre “ativo”.

6. Observações e boas práticas

  • E3DataAccess é documentada oficialmente apenas para aplicações 32-bit; a partir da versão 4.5.208 do E3Server, as conexões via E3DataAccess e E3AccessLayer não consomem mais licenças de Viewer.
  • Os métodos Domain.Refresh e Domain.Stop do objeto [?Server] exigem E3 V6.1 Build 046 ou superior — não usados neste caso, mas fazem parte da mesma árvore [?Server].Domain.
  • Como o enum de State é o mesmo em Domain.State e em Domain.Servers.LocalServer.State/RemoteServer.DomainState, é possível montar um dashboard completo do par de redundância (local + remoto) com as mesmas Tags-ponte.
  • Evite depender de Domain.State (sem o caminho Servers.LocalServer) para diferenciar A de B — em conexões via domínio ele reflete o servidor ativo, não necessariamente o host onde o script roda.

Artigos relacionados


Print Friendly, PDF & Email

Este artigo foi útil? Was this helpful?

Classificação média - Average rating 0 / 5. Count: 0

Deixe seu Comentário

Seu endereço de e-mail não será publicado. Campos marcados com asterisco são obrigatórios *