#Compatibilidade

0 Seguidores · 5 Postagens

Compatibilidade é a capacidade de dois sistemas funcionarem juntos sem ter que serem alterados para isso.

InterSystems Oficial Danusa Calixto · Abr. 3, 2025

Resumo de Alertas

Alerta ID Produto & Versões Afectadas Requisitos Explícitos
DP-439207  InterSystems IRIS® data platform 2024.3 (AIX) Instalações AIX Usando JSON e conjuntos de Caracteres Unicode non-Latin-1 
DP-439280  InterSystems IRIS 2024.3 (containers com IntegratedML)  IntegratedML Containers usando TensorFlow

Detalhes dos Alertas

DP-439207 - Problemas no Parser JSON Unicode em AIX

0
0 28
InterSystems Oficial Danusa Calixto · jan 29, 2025

As primeiras prévias para desenvolvedores da plataforma de dados InterSystems IRIS® data platform, InterSystems IRIS® for Health, e HealthShare® Health Connect 2025.1 foram publicadas no site de prévia para desenvolvedores do WRC. Os contêineres podem ser encontrados em nosso registro de contêineres e são marcados como última prévia.

0
0 28
Artigo Heloisa Paiva · Set. 2, 2024 5m read

Faz bastante tempo desde a última vez que escrevi uma postagem de atualização do IoP.

image

Então, o que há de novo desde o lançamento da interface de linha de comando IoP?

Dois novos grandes recursos foram adicionados ao IoP:

  • Rebranding: o módulogrongier.pex foi renomeado para iop para refletir o novo nome do projeto.
  • suporte Async: IoP agora suporta funções assíncronas e co-rotinas.

Rebranding

O módulo grongier.pex foi renomeado para iop para refletir o novo nome do projeto.

O módulo grongier.pex ainda está disponível para compatibilidade retroativa, mas será removido no futuro.

suporte Async

O IoP suporta chamadas assíncronas há um bom tempo, mas não era possível usar funções e co-rotinas assíncronas diretamente nele.

Antes de pular dentro desse novo recurso, vou explicar como chamadas assíncronas funcionam no InterSystems IRIS e apresentar dois exemplos de como usar chamadas assíncronas IoP.

Chamadas async legado

Vamos ver como chamadas async legado funcionam:

from iop import BusinessProcess
from msg import MyMessage


class MyBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        self.send_request_async("Python.MyBO", msg_one,completion_key="1")
        self.send_request_async("Python.MyBO", msg_two,completion_key="2")

    def on_response(self, request, response, call_request, call_response, completion_key):
        if completion_key == "1":
            self.response_one = call_response
        elif completion_key == "2":
            self.response_two = call_response

    def on_complete(self, request, response):
        self.log_info(f"Received response one: {self.response_one.message}")
        self.log_info(f"Received response two: {self.response_two.message}")

Basicamente elas funcionam da mesma maneira que chamadas async funcionam em IRIS. O método send_request_async envia uma requisição ao Business Operation e o método on_response é chamado quando a resposta é recebida.

Você pode distinguir as respostas pelo parâmetro completion_key

Enviar múltiplas requisições síncronas

Não é exatamente um novo recurso, mas vale a pena mencionar que você pode mandar múltiplas requisições síncronas em paralelo:

from iop import BusinessProcess
from msg import MyMessage


class MyMultiBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        tuple_responses = self.send_multi_request_sync([("Python.MyMultiBO", msg_one),
                                                        ("Python.MyMultiBO", msg_two)])

        self.log_info("All requests have been processed")
        for target,request,response,status in tuple_responses:
            self.log_info(f"Received response: {response.message}")

Aqui estamos mandando duas requisições ao mesmo Business Operation em paralelo.

A resposta é uma tupla com o objetivo, requisição, resposta e status de cada chamada.

É bastante útil quando você precisa enviar múltiplas requisições e não se importa com a ordem das respostas.

Funções Async e co-rotinas

Agora vamos ver como usar funções assíncronas e co-rotinas no IoP:

import asyncio

from iop import BusinessProcess
from msg import MyMessage


class MyAsyncNGBP(BusinessProcess):

    def on_message(self, request):

        results = asyncio.run(self.await_response(request))

        for result in results:
            print(f"Received response: {result.message}")

    async def await_response(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        # use asyncio.gather to send multiple requests asynchronously
        # using the send_request_async_ng method
        tasks = [self.send_request_async_ng("Python.MyAsyncNGBO", msg_one),
                 self.send_request_async_ng("Python.MyAsyncNGBO", msg_two)]

        return await asyncio.gather(*tasks)

Neste exemplo, estamos enviando múltiplas requisições para o mesmo Business Operation em paralelo usando o método send_request_async_ng.

Se você leu esse post cuidadosamente até este ponto, por favor comente "Boomerang". Isso pode ser um detalhe para você, mas para mim significa muito. Obrigado!

O método await_response é uma co-rotina que envia múltiplas requisições e espera por todas as respostas. Graças a função asyncio.gather`, podemos esperar por todas as respostas serem recebidas em paralelo

Os benefícios das funções e co-rotinas assíncronas são:

  • Melhor performance: você pode enviar múltiplas requisições em paralelo.
  • Mais fácil de ler e manter: você pode usar a palavra chave await para esperar por respostas.
  • Maior flexibilidade: você pode usar o módulo asyncio para criar fluxos de trabalho complexos
  • Mais controle: você pode usar o módulo asyncio para lidar com exceções e timeouts.

Conclusão

Quais são as diferenças entre send_request_async, send_multi_request_sync e send_request_async_ng?

  • send_request_async: envia uma requisição ao Business Operation e espera a resposta se o método on_response for implementado e o parâmetro completion_key usado
    • benefício: você pode usar chamadas assíncronas da maneira que está acostumado.
    • desvantagem: pode ser difícil de manter se você precisa enviar múltiplas requisições em paralelo.
  • send_multi_request_sync: envia múltiplas requisições ao mesmo Business Operation em paralelo e espera por todas as respostas para serem recebidas.
    • benefício: fácil de usar.
    • desvantagem: você pode controlar a ordem das respostas (quero dizer se a lista de respostas não for ordenada)
  • send_request_async_ng: envia múltiplas requisições ao mesmo Business Operation em paralelo e espera por todas as respostas.
    • benefício: você pode controlar a ordem das respostas
    • desvantagem: você precisa usar funções e co-rotinas assíncronas.

Feliz multithreading!

0
0 43
Artigo Danusa Calixto · Set. 1, 2023 4m read

Visão geral

Com o cross-skilling do objectScript do IRIS para o Python, ficam claras algumas diferenças fascinantes na sintaxe.

Uma dessas áreas é como o Python retorna Tuplas de um método com desempacotamento automático.

Efetivamente, isso se apresenta como um método que retorna vários valores. Que invenção incrível :)

out1, out2 = some_function(in1, in2)

O ObjectScript tem uma abordagem diferente com o ByRef e os parâmetros de saída.

Do ##class(some_class).SomeMethod(.inAndOut1, in2, .out2)

Onde:

  • inAndOut1 é o ByRef
  • out2 é a saída

O ponto à esquerda (".") na frente do nome da variável passa o ByRef e a saída.

A finalidade deste artigo é descrever como a comunidade do utilitário PyHelper foi otimizada para oferecer uma maneira pythônica de aproveitar o ByRef e os parâmetros de saída. Ele dá acesso a %objlasterror e tem uma abordagem para lidar com o tipo None do Python.
 

ByRef de exemplo

A invocação normal para o embedded python seria:

oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('er12345')

Quando a abertura desse método falha, a variável "oHL7" é uma string vazia.
Na assinatura desse método, há um parâmetro de status disponível para o object script que fornece uma explicação do problema exato.
Por exemplo:

  • O registro pode não existir
  • Não foi possível abrir o registro no modo de simultaneidade exclusiva padrão ("1"), dentro do tempo limite
ClassMethod %OpenId(id As %String = "", concurrency As %Integer = -1, ByRef sc As %Status = {$$$OK}) As %ObjectHandle

O método TupleOut pode ajudar no retorno do valor do argumento sc, de volta a um contexto python.
 

> oHL7,tsc=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['sc'],1,'er145999', 0)
> oHL7
''
> iris.cls("%SYSTEM.Status").DisplayError(tsc)
ERROR #5809: Object to Load not found, class 'EnsLib.HL7.Message', ID 'er145999'1
```

A lista ['sc'] contém um único item nesse caso. Ela pode retornar vários valores Byref, e na ordem especificada. O que é útil para descompactar automaticamente as variáveis pretendidas do Python.

Exemplo de como lidar com um parâmetro de saída

Código em Python:

> oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('145')
> oHL7.GetValueAt('<%MSH:9.1')
''

A string retornada está vazia, mas isso se deve ao elemento realmente estar vazio OU algo que deu errado.
No object script, há também um parâmetro de status de saída (pStatus) que pode ser acessado para determinar essa condição.

Código em object script:

> write oHL7.GetValueAt("<%MSH:9.1",,.pStatus)
''
> Do $System.Status.DisplayError(pStatus)
ERROR <Ens>ErrGeneral: No segment found at path '<%MSH'

Com TupleOut, a funcionalidade equivalente pode ser obtida ao retornar e descompactar ambos o valor de retorno do método E o parâmetro de saída do status.

Código em Python:

> hl7=iris.cls("EnsLib.HL7.Message")._OpenId(145,0)
> val, status = iris.cls("alwo.PyHelper").TupleOut(hl7,"GetValueAt",['pStatus'],1,"<&$BadMSH:9.1")
> val==''
True
> iris.cls("%SYSTEM.Status").IsError(status)
1
> iris.cls("%SYSTEM.Status").DisplayError(status)
ERROR <Ens>ErrGeneral: No segment found at path '<&$BadMSH'1

###Variável especial %objlasterror

No objectscript, há acesso a variáveis de porcentagem no escopo do método.
Há cenários em que detectar ou acessar a variável especial %objlasterror é útil após chamar uma API de terceiros ou CORE
O método TupleOut permite o acesso a %objlasterror, como se tivesse sido definido como um parâmetro de saída, ao invocar métodos do Python

> del _objlasterror

> out,_objlasterror=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['%objlasterror'],1,'er145999', 0) 

> iris.cls("%SYSTEM.Status").DisplayError(_objlasterror)
ERROR #5809: Object to Load not found, class 'EnsLib.HL7.Message', ID 'er145999'1

Quando None não é uma String

O TupleOut lida com as referências a None do Python como objectscript indefinido. Isso permite que os parâmetros sejam padronizados e os métodos se comportem de forma consistente.
Isso é importante, por exemplo, com %Persistent::%OnNew, em que o método %OnNew não é acionado quando None é fornecido para initvalue, mas seria acionado se uma string vazia fosse fornecida.

No objectscript, a implementação pode dizer:

do oHL7.myMethod("val1",,,"val2")

Observe a ausência de variáveis entre vírgulas.

O TupleOut facilita o mesmo comportamento com:

Python:

iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,"val1",None,None,"val2")

Outra maneira de considerar isso é poder ter uma implementação de uma linha de código de invocação, com um comportamento flexível dependendo da pré-configuração das variáveis:

Object Script:

set arg1="val1"
kill arg2
kill arg3
set arg4="val2"
do oHL7.myMethod(.arg1, .arg2, .arg3, .arg4)

O TupleOut facilita o mesmo comportamento com:

Python:

arg1="val1"
arg2=None
arg3=None
arg4="val2"
iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,arg1,arg2,arg3,arg4)

Lista e dicionários

Ao lidar com parâmetros para entrada, ByRef e saída, o TupleOut utiliza o mapeamento automático do PyHelper entre:
Listas do IRIS e do Python
Arrays do IRIS e do Python
Onde é preciso sempre usar strings para representar as chaves do dicionário ao passar de Arrays do IRIS para tipos Dict do Python.

Conclusão

Espero que este artigo ajude a inspirar novas ideias, discussões e sugestões sobre o Embedded Python.

Também espero que incentive a explorar a flexibilidade do IRIS em se adaptar facilmente para enfrentar novos desafios.

0
0 52
Pergunta Fabio Silva · Jun. 25, 2021

Bom dia.

Alguém tem algum case de utilização do Caché / Ensemble versões 2009, 2012 e 2018 no ambiente produtivo com o ESXI 7.0 da vmware?

Falei com a InterSystems e eles responderam que não homologam virtualização, porém gostaria de saber se alguém tem algum caso de uso.

Obrigado.

5
0 143