Compartilhar via


Serviço de Metadados do Azure: Eventos Agendados para VMs do Windows

Aplica-se a: ✔️ VMs do Windows ✔️ Conjuntos de dimensionamento flexíveis ✔️ Conjuntos de dimensionamento uniformes

Os eventos agendados são um serviço de metadados do Azure que dá ao aplicativo tempo para se preparar para a manutenção de máquinas virtuais (VM). Ele fornece informações sobre eventos de manutenção futuros (por exemplo, reinicializar) para que seu aplicativo possa se preparar e limitar a interrupção. Ele está disponível para todos os tipos de Máquinas Virtuais do Azure, incluindo PaaS e IaaS no Windows e no Linux.

Para saber mais sobre os Eventos Agendados no Linux, confira Eventos agendados para VMs do Linux.

Os eventos agendados fornecem notificações proativas sobre eventos futuros, para obter informações reativas sobre eventos que já ocorreram. Confira Informações de disponibilidade da VM no Azure Resource Graph e Criar regra de alerta de disponibilidade para máquina virtual do Azure.

Observação

Eventos Agendados estão disponível geralmente em todas as regiões do Azure. Consulte Disponibilidade de Versão e Região para obter informações sobre a versão mais recente.

Por que usar Eventos Agendados?

Muitos aplicativos podem se beneficiar do tempo para se preparar para a manutenção de VMs. O tempo pode ser usado para executar tarefas específicas de aplicativo que melhoram a disponibilidade, a confiabilidade e a capacidade de manutenção, incluindo:

  • Ponto de verificação e restauração.
  • Descarregamento de conexão.
  • Failover de réplica primária.
  • Remoção de um pool de balanceador de carga.
  • Log de eventos.
  • Desligamento normal.

Com Eventos Agendados, seu aplicativo pode descobrir quando a manutenção ocorrerá e acionará tarefas para limitar seu impacto.

Os eventos agendados fornecem eventos nos seguintes casos de uso:

Noções básicas

O Serviço de Metadados do Azure expõe informações sobre a execução de VMs usando um ponto de extremidade REST acessível de dentro da VM. As informações estão disponíveis por meio de um IP não roteável e não são expostas fora da VM.

Escopo

Os eventos agendados são entregues e podem ser confirmados por:

  • Máquinas virtuais autônomas.
  • Todas as VMs em um serviço de nuvem do Azure (clássico).
  • Todas as VMs em um conjunto de disponibilidade.
  • Todas as VMs em um grupo de posicionamento do conjunto de dimensionamento.

Eventos Agendados para todas as VMs (máquinas virtuais) em um conjunto de disponibilidade inteiro ou um grupo de posicionamento para um conjunto de dimensionamento de máquinas virtuais são entregues a todas as outras VMs no mesmo grupo ou conjunto, independentemente do uso da zona de disponibilidade.

Como resultado, verifique o campo Resources no evento para identificar quais VMs são afetadas.

Observação

Máquinas Virtuais aceleradas por GPU em um conjunto de dimensionamento usando um domínio de falha (FD = 1) receberão apenas eventos agendados para o recurso afetado. Os eventos não serão transmitidos para todas as VMs no mesmo grupo de colocação.

Descoberta do ponto de extremidade

Para VMs habilitadas para VNET, o serviço de metadados está disponível de um IP não roteável estático, 169.254.169.254. O ponto de extremidade completo para a versão mais recente dos eventos agendados é:

http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01

Se a VM não for criada em uma Rede Virtual, os casos padrão para serviços de nuvem e VMs clássicas, uma lógica adicional será necessária para descobrir o endereço IP a ser usado. Consulte esse exemplo para saber como descobrir o ponto de extremidade do host.

Disponibilidade de versão e região

O serviço de Eventos Agendados tem controle de versão. As versões são obrigatórias; a versão atual é 2020-07-01.

Versão Tipo de Versão Regiões Notas de versão
2020-07-01 Disponibilidade geral Todos
  • Suporte adicionado à Duração do Evento
  • 01-08-2019 Disponibilidade geral Todos
  • Adição de suporte para o EventSource
  • 01-04-2019 Disponibilidade geral Todos
  • Adição de suporte para a Descrição do Evento
  • 2019-01-01 Disponibilidade geral Todos
  • Suporte adicionado para Conjuntos de Dimensionamento de Máquinas Virtuais EventType 'Terminate'
  • 2017-11-01 Disponibilidade geral Todos
  • Suporte adicionado para o EventType de remoção de VM spot “Preempt”
  • 2017-08-01 Disponibilidade geral Todos
  • Removido o sublinhado inicial dos nomes de recursos para as VMs de IaaS
  • Requisito de cabeçalho de metadados imposto para todas as solicitações
  • 2017-03-01 Visualização Todos
  • Versão inicial
  • Observação

    Versões prévias anteriores de Eventos Agendados compatíveis {mais recentes} como a api-version. Esse formato não é mais suportado e será substituído no futuro.

    Habilitação e desabilitação de Eventos Agendados

    Eventos Agendados são habilitados para o serviço na primeira vez em que você faz uma solicitação para eventos. Você deve esperar uma resposta atrasada em sua primeira chamada de até dois minutos e começará a receber eventos dentro de cinco minutos. O serviço Eventos Agendados é desabilitado se ele não fizer uma solicitação ao ponto de extremidade por 24 horas.

    Manutenção iniciada pelo usuário

    A manutenção de VMs iniciada pelo usuário pelo Portal do Azure, API, CLI ou PowerShell resulta em um evento agendado. Você pode então testar a lógica de preparação de manutenção em seu aplicativo e permite que seu aplicativo se prepare para manutenção iniciada pelo usuário.

    Se você reinicia uma VM, um evento com o tipo Reboot é agendado. Se você reimplanta uma VM, um evento com o tipo Redeploy é agendado. Normalmente, os eventos com uma fonte de eventos do usuário podem ser aprovados imediatamente para evitar um atraso nas ações iniciadas pelo usuário. Recomendados que haja uma VM primária e uma secundária comunicando e aprovando eventos agendados gerados pelo usuário caso a VM primária não responda. A aprovação imediata de eventos impede atrasos na recuperação do aplicativo para um bom estado.

    Há suporte para eventos agendados para atualizações ou novas imagens do sistema operacional convidado de Conjuntos de Dimensionamento de Máquinas Virtuais para tamanhos de VM de uso geral que dão suporte apenas a atualizações de preservação de memória. Ela não funciona para as séries G, M, N e H. Os eventos agendados para atualizações ou criação de novas imagens do sistema operacional do Conjunto de Dimensionamento de Máquinas Virtuais Convidadas estão desabilitados por padrão. Para habilitar eventos agendados dessas operações, primeiro habilite-os por meio de OSImageNotificationProfile.

    Usar a API

    Visão geral de alto nível

    Há dois componentes principais para lidar com Eventos Agendados, preparação e recuperação. Todos os eventos agendados atuais que afetam uma VM estão disponíveis para leitura por meio do ponto de extremidade Eventos Agendados do IMDS. Quando o evento atinge um estado terminal, ele é removido da lista de eventos. O diagrama a seguir mostra as várias transições de estado que um único evento agendado pode experimentar:

    Diagrama de estado mostrando as diversas transições que um evento agendado pode ter.

    Para eventos no estado EventStatus:"Scheduled", você precisará executar etapas para preparar sua carga de trabalho. Depois que a preparação for concluída, você deverá aprovar o evento usando a API de evento agendado. Caso contrário, o evento será aprovado automaticamente quando o horário NotBefore for atingido. Se a VM estiver em infraestrutura compartilhada, o sistema aguardará que todos os outros locatários no mesmo hardware também aprovem o trabalho ou o tempo limite. Depois que as aprovações são coletadas de todas as VMs afetadas ou a hora de NotBefore é atingida, o Azure gera uma nova carga de evento agendada com EventStatus:"Started" e dispara o início do evento de manutenção. Quando o evento atinge um estado terminal, ele é removido da lista de eventos. Isso serve como o sinal para o cliente recuperar suas VMs.

    Veja abaixo o código psudeo que demonstra um processo de como ler e gerenciar eventos agendados em seu aplicativo:

    current_list_of_scheduled_events = get_latest_from_se_endpoint()
    #prepare for new events
    for each event in current_list_of_scheduled_events:
      if event not in previous_list_of_scheduled_events:
        prepare_for_event(event)
    #recover from completed events
    for each event in previous_list_of_scheduled_events:
      if event not in current_list_of_scheduled_events:
        receover_from_event(event)
    #prepare for future jobs
    previous_list_of_scheduled_events = current_list_of_scheduled_events
    

    Como os eventos agendados geralmente são usados para aplicativos com requisitos de alta disponibilidade, há alguns casos excepcionais que devem ser considerados:

    1. Depois que um evento agendado for concluído e removido da matriz, não haverá mais nenhum impacto sem um novo evento, incluindo outro evento EventStatus:"Scheduled"
    2. O Azure monitora operações de manutenção em toda a frota e, em circunstâncias raras, determina que uma operação de manutenção tem um risco muito alto para ser aplicada. Nesse caso, o evento agendado vai diretamente de “Scheduled” para removido da matriz de eventos
    3. No caso de falha de hardware, o Azure ignora o estado “Scheduled” e passa imediatamente para o estado EventStatus:"Started".
    4. Embora o evento ainda esteja no estado EventStatus:"Started", pode haver outro impacto de uma duração menor do que o anunciado no evento agendado.

    Como parte da garantia de disponibilidade do Azure, as VMs em domínios de falha diferentes não serão afetadas por operações de manutenção de rotina ao mesmo tempo. No entanto, elas podem ter operações serializadas uma após a outra. As VMs em um domínio de falha podem receber eventos agendados com EventStatus:"Scheduled" logo após a conclusão da manutenção de outro domínio de falha. Independentemente da arquitetura que você escolheu, sempre continue verificando se há novos eventos pendentes em suas VMs.

    Embora os intervalos exatos de eventos variem, o diagrama a seguir fornece uma diretriz aproximada de como uma operação de manutenção típica ocorre:

    • EventStatus:"Scheduled" to Approval Timeout: 15 minutos
    • Duração do impacto: 7 segundos
    • EventStatus:"Started" to Completed (evento removido da matriz Eventos): 10 minutos

    Diagrama de uma linha do tempo mostrando o fluxo de um evento agendado.

    Todas as operações que afetam a disponibilidade da VM resultarão em um evento agendado. No entanto, nem todos os eventos agendados aparecerão em outras superfícies do Azure, como Logs de Atividades do Azure ou Integridade de Recursos. Verificar eventos agendados regularmente garantirá que você tenha as informações mais atualizadas sobre quaisquer impactos futuros em suas VMs.

    Cabeçalhos

    Ao consultar o Serviço de Metadados você deverá fornecer o cabeçalho Metadata:true para garantir que a solicitação não foi redirecionada de forma involuntária. O cabeçalho Metadata:true é necessário para todas as solicitações de eventos programados. A não inclusão do cabeçalho na solicitação resulta em uma resposta de "Solicitação Incorreta" do Serviço de Metadados.

    Consulta de eventos

    Você pode consultar Eventos Agendados realizando a chamada a seguir:

    Exemplo de bash

    curl -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    Exemplo do PowerShell

    Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01" | ConvertTo-Json -Depth 64
    

    Exemplo de Python

    import json
    import requests
    
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    header = {'Metadata' : 'true'}
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    

    Uma resposta contém uma matriz de eventos agendados. Uma matriz vazia significa que não há eventos agendados no momento. No caso de haver eventos agendados, a resposta contém uma matriz de eventos.

    {
        "DocumentIncarnation": {IncarnationID},
        "Events": [
            {
                "EventId": {eventID},
                "EventType": "Reboot" | "Redeploy" | "Freeze" | "Preempt" | "Terminate",
                "ResourceType": "VirtualMachine",
                "Resources": [{resourceName}],
                "EventStatus": "Scheduled" | "Started",
                "NotBefore": {timeInUTC},       
                "Description": {eventDescription},
                "EventSource" : "Platform" | "User",
                "DurationInSeconds" : {timeInSeconds},
            }
        ]
    }
    

    Propriedades do evento

    Propriedade Descrição
    Encarnação do documento Inteiro que aumenta quando a matriz de eventos é alterada. Documentos com a mesma encarnação contêm as mesmas informações de evento, e a encarnação é incrementada quando um evento é alterado.
    EventId Identificador global exclusivo para esse evento.

    Exemplo:
    • 602d9444-d2cd-49c7-8624-8643e7171297
    EventType Impacto esperado que esse evento causará.

    Valores:
    • Freeze: A máquina virtual está agendada para ser colocada em pausa por alguns segundos. A conectividade de CPU e rede pode ser suspensa, mas não há nenhum impacto na memória ou nos arquivos abertos.
    • Reboot: A Máquina Virtual está agendada para ser reinicializada (a memória não persistente é perdida). Em casos raros, uma VM agendada para EventType:"Reboot" pode enfrentar um evento de congelamento em vez de uma reinicialização. Siga as instruções acima para saber se o evento foi concluído e se é seguro restaurar sua carga de trabalho.
    • Redeploy: A Máquina Virtual está agendada para ser movida para outro nó (os discos efêmeros são perdidos).
    • Preempt: A máquina virtual spot está sendo excluída (discos efêmeros são perdidos). Esse evento é disponibilizado assim que possível
    • Terminate: a máquina virtual está agendada para ser excluída.
    ResourceType O tipo de recurso que esse evento afeta.

    Valores:
    • VirtualMachine
    Recursos A lista de recursos que esse evento afeta.

    Exemplo:
    • ["FrontEnd_IN_0", "BackEnd_IN_0"]
    EventStatus Status desse evento.

    Valores:
    • Scheduled: Esse evento está agendado para ser iniciado após o tempo especificado na propriedade NotBefore.
    • Started: Esse evento foi iniciado.
    Nenhum Completed ou status semelhante é fornecido em nenhum momento. O evento não é mais retornado quando é concluído.
    NotBefore Tempo após o qual esse evento pode começar. É garantido que o evento não começará antes dessa hora. Ficará em branco se o evento já iniciou

    Exemplo:
    • Segunda-feira, 19 de setembro de 2016 18:29:47 GMT
    Descrição A descrição deste evento.

    Exemplo:
    • O servidor host está passando por manutenção.
    EventSource Iniciador do evento.

    Exemplo:
    • Platform: esse evento é iniciado pela plataforma.
    • User: esse evento é iniciado pelo usuário.
    DurationInSeconds A duração esperada da interrupção causada pelo evento. Pode haver impactos secundários de duração mais curta durante a janela de impacto.

    Exemplo:
    • 9: A interrupção causada pelo evento durará 9 segundos.
    • 0: o evento não interromperá a VM nem afetará a disponibilidade dela (por exemplo, atualização na rede)
    • -1: O valor padrão usado se a duração do impacto for desconhecida ou não aplicável.

    Agendamento do evento

    Cada evento é agendado uma quantidade mínima de tempo no futuro com base no tipo de evento. Esse tempo é refletido na propriedades NotBefore de um evento.

    EventType Aviso mínimo
    Congelamento 15 minutos
    Reboot 15 minutos
    Reimplantar 10 minutos
    Terminate Configurável pelo usuário: De 5 a 15 minutos

    Isso significa que você pode detectar um evento futuro agendado pelo menos pelo tempo mínimo de aviso antes da ocorrência do evento. Depois que um evento for agendado, ele passará para o estado Started depois de ser aprovado ou não antes do tempo NotBefore transcorrer. No entanto, em casos raros, a operação será cancelada pelo Azure antes de ser iniciada. Nesse caso, o evento será removido da matriz Eventos e o impacto não ocorrerá como agendado anteriormente.

    Observação

    Em alguns casos, o Azure é capaz de prever a falha do host devido a hardware degradado e agendará uma migração para tentar reduzir a interrupção em seu serviço. As máquinas virtuais afetadas receberão um evento agendado com um NotBefore, que normalmente é de alguns dias no futuro. O tempo real depende da avaliação de risco da falha prevista. O Azure tenta avisar com sete dias de antecedência, quando possível, mas o tempo real varia e poderá ser menor se houver uma previsão de grande chance de falha de software iminente. Para minimizar o risco para o serviço caso o hardware falhe antes da migração iniciada pelo sistema, recomendamos que você reimplante sua máquina virtual assim que possível.

    Observação

    Quando o nó de host apresenta uma falha de hardware, o Azure ignora o período mínimo de aviso prévio e inicia imediatamente o processo de recuperação das máquinas virtuais afetadas. Isso reduz o tempo de recuperação, caso as VMs afetadas não consigam responder. Durante o processo de recuperação, um evento será criado para todas as VMs afetadas com EventType = Reboot e EventStatus = Started.

    Frequência de sondagem

    Você pode fazer uma sondagem do ponto de extremidade para buscar atualizações com a frequência que desejar. No entanto, quanto maior o tempo entre as solicitações, mais tempo você pode perder para reagir a um evento futuro. A maioria dos eventos tem entre 5 e 15 minutos de aviso prévio, embora, em alguns casos, esse aviso possa ser de apenas 30 segundos. Para garantir que você tenha o máximo de tempo possível para realizar ações de mitigação, recomendamos monitorar o serviço uma vez por segundo.

    Iniciar um evento

    Após a descoberta de um evento futuro e concluído sua lógica de desligamento normal, você poderá aprovar o evento pendente fazendo uma chamada POST para o Serviço de Metadados com EventId. Essa chamada indica para o Azure que ele pode encurtar o tempo mínimo de notificação (quando possível). O evento pode não iniciar imediatamente após a aprovação pois, em alguns casos, o Azure exige a aprovação de todas as VMs hospedadas no nó antes de prosseguir com o evento.

    A seguir vemos o exemplo de JSON esperado no corpo da solicitação POST. A solicitação deve conter uma lista de StartRequests. Cada StartRequest contém o EventId para o evento que você deseja agilizar:

    {
    	"StartRequests" : [
    		{
    			"EventId": {EventId}
    		}
    	]
    }
    

    O serviço sempre retornará um código de sucesso 200 se uma ID de evento válida for passada, mesmo que o evento já tenha sido aprovado por uma outra VM. Um código de erro 400 indica que o cabeçalho ou o conteúdo da solicitação foi malformado.

    Observação

    Os eventos não continuarão, a menos que sejam aprovados por meio de uma mensagem POST ou não antes do tempo decorrido. Isso inclui eventos disparados pelo usuário, como reinicializações de VM do portal do Azure.

    Exemplo de bash

    curl -H Metadata:true -X POST -d '{"StartRequests": [{"EventId": "f020ba2e-3bc0-4c40-a10b-86575a9eabd5"}]}' http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    Exemplo do PowerShell

    Invoke-RestMethod -Headers @{"Metadata" = "true"} -Method POST -body '{"StartRequests": [{"EventId": "5DD55B64-45AD-49D3-BBC9-F57D4EA97BD7"}]}' -Uri http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01 | ConvertTo-Json -Depth 64
    

    Exemplo de Python

    import json
    import requests
    
    def confirm_scheduled_event(event_id):  
       # This payload confirms a single event with id event_id
       payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
       response = requests.post("http://169.254.169.254/metadata/scheduledevents", 
                                headers =  {'Metadata' : 'true'}, 
                                params = {'api-version':'2020-07-01'}, 
                                data = payload)    
       return response.status_code
    

    Observação

    Reconhecer um evento permite que o evento prossiga para todos Resources no evento, e não apenas a VM que reconhece o evento. Portanto, é possível eleger um líder para coordenar o reconhecimento, que pode ser tão simples como a primeira máquina no campo Resources.

    Respostas de exemplo

    Os eventos a seguir são um exemplo que foi visto por duas VMs que foram migradas ao vivo para outro nó.

    O DocumentIncarnation muda sempre que há novas informações em Events. Uma aprovação do evento permitiria que o congelamento continuasse para WestNO_0 e WestNO_1. O DurationInSeconds de -1 indica que a plataforma não sabe quanto tempo a operação levará.

    {
        "DocumentIncarnation":  1,
        "Events":  [
                   ]
    }
    
    {
        "DocumentIncarnation":  2,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Scheduled",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "Mon, 11 Apr 2022 22:26:58 GMT",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  3,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Started",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  4,
        "Events":  [
                   ]
    }
    
    

    Exemplo de Python

    O exemplo a seguir consulta o Serviço de Metadados para eventos agendados e aprova cada evento pendente:

    #!/usr/bin/python
    import json
    import requests
    from time import sleep
    
    # The URL to access the metadata service
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    # This must be sent otherwise the request will be ignored
    header = {'Metadata' : 'true'}
    # Current version of the API
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    def confirm_scheduled_event(event_id):  
        # This payload confirms a single event with id event_id
        # You can confirm multiple events in a single request if needed      
        payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
        response = requests.post(metadata_url, 
                                headers= header,
                                params = query_params, 
                                data = payload)    
        return response.status_code
    
    def log(event): 
        # This is an optional placeholder for logging events to your system 
        print(event["Description"])
        return
    
    def advanced_sample(last_document_incarnation): 
        # Poll every second to see if there are new scheduled events to process
        # Since some events may have necessarily short warning periods, it is 
        # recommended to poll frequently
        found_document_incarnation = last_document_incarnation
        while (last_document_incarnation == found_document_incarnation):
            sleep(1)
            payload = get_scheduled_events()    
            found_document_incarnation = payload["DocumentIncarnation"]        
            
        # We recommend processing all events in a document together, 
        # even if you won't be actioning on them right away
        for event in payload["Events"]:
    
            # Events that have already started, logged for tracking
            if (event["EventStatus"] == "Started"):
                log(event)
                
            # Approve all user initiated events. These are typically created by an 
            # administrator and approving them immediately can help to avoid delays 
            # in admin actions
            elif (event["EventSource"] == "User"):
                confirm_scheduled_event(event["EventId"])            
                
            # For this application, freeze events less that 9 seconds are considered
            # no impact. This will immediately approve them
            elif (event["EventType"] == "Freeze" and 
                int(event["DurationInSeconds"]) >= 0  and 
                int(event["DurationInSeconds"]) < 9):
                confirm_scheduled_event(event["EventId"])
                
            # Events that may be impactful (for example reboot or redeploy) may need custom 
            # handling for your application
            else: 
                #TODO Custom handling for impactful events
                log(event)
        print("Processed events from document: " + str(found_document_incarnation))
        return found_document_incarnation
    
    def main():
        # This will track the last set of events seen 
        last_document_incarnation = "-1"
    
        input_text = "\
            Press 1 to poll for new events \n\
            Press 2 to exit \n "
        program_exit = False 
    
        while program_exit == False:
            user_input = input(input_text)    
            if (user_input == "1"):                        
                last_document_incarnation = advanced_sample(last_document_incarnation)
            elif (user_input == "2"):
                program_exit = True       
    
    if __name__ == '__main__':
        main()
    

    Próximas etapas