在ABAP中创建一个简单的守护进程

原文地址:Create a simple Daemon in ABAP

目录

  • 一、ABAP语言中的守护进程是什么?
  • 二、ABAP 守护进程框架 (ADF)
  • 三、ABAP 守护进程类
  • 四、创建一个简单的ABAP守护进程
    • 步骤1:创建一个新的ABAP Daemon类
    • 步骤2:实现ON_ACCEPT方法
    • 第三步:实现ON_START方法
    • 第四步:实现ON_TIMEOUT方法
    • 第5步:实现ON_MESSAGE方法
    • 第6步:实现静态方法START
    • 第7步:实现静态方法SEND并运行守护进程
    • 第 8 步:停止 ABAP 守护进程
  • 五、守护进程用例。
  • 六、结论

一、ABAP语言中的守护进程是什么?

守护程序是一种实用程序,它自身连续运行,无需交互式用户在后台多任务操作系统上的控制,以监视和处理某些子系统或对事件立即做出反应。守护进程在预定义的时间或响应某些事件执行显式操作。

ABAP 守护进程框架 (ADF-ABAP Daemon Framework) 提供的 ABAP 守护进程功能与 Linux 或 Windows 中的对应功能更加相似。它们通过在具有无限生命周期的会话中运行来以可靠的方式处理事件。ABAP 程序可以通过使用 ABAP 消息传递通道和消息类型推送通道协议 (PCP) 向守护程序发送消息来与守护程序进行通信,PCP 是一种类似于简单 HTTP 消息的通信格式。

守护进程对错误的应对非常可靠,即守护进程会话在遇到错误(E/A/X 消息)后不会终止。但是,每次运行时错误或类型 E、A 或 X 的消息导致程序终止时,都会自动再次创建 ABAP 守护程序。当其 AS 实例关闭时,可以通过创建包含与前面的守护程序相同的上下文信息的新守护程序来将守护程序移动到另一个 AS 实例。这使得新的守护进程能够完成相同的工作。

二、ABAP 守护进程框架 (ADF)

SAP Netweaver 7.52 将 ABAP Daemon Framework 或简称 ADF 作为一项新功能。ADF 是一个 API,允许您在 ABAP 中创建和管理守护程序。ABAP 守护进程是 ABAP 守护进程类的实例,位于应用程序服务器的特殊 ABAP 守护进程会话中。ABAP程序本身使用ABAP守护进程管理器来访问ABAP守护进程。

如前所述,ABAP 守护进程的处理发生在后台并使用事件进行控制。守护程序或ABAP运行时框架的用户可以引发ABAP守护程序事件,守护程序使用预定义的接口方法对此做出反应。守护进程必须始终准备好对入站事件做出反应,这是通过以非阻塞模式运行 ABAP 守护进程处理来确保的,以防止 ABAP 守护进程处理中出现运行时错误 DAEMON_ILLEGAL_STATEMENT 以及随后重新启动守护进程。

有关ADF实现和 ABAP 守护进程类的详细信息扩展可以在 ABAP 关键字文档和本博客文章系列中找到。在这里我想更多地关注如何通过实现守护进程类来创建守护进程的过程。

三、ABAP 守护进程类

ABAP守护进程类是一个全局类,继承自抽象系统类CL_ABAP_DAEMON_EXT_BASE。ABAP 守护程序类继承了接口 IF_ABAP_DAEMON_EXTENSION 的方法,如果在 ABAP 守护程序类中实现了这些事件,则ABAP 守护程序类将使用这些方法对ABAP 守护程序事件做出反应。这些方法的详细解释可以在文档的相关部分找到。

ABAP 守护程序类可以包含更多辅助方法,并且可以在其方法中调用任意数量的其他过程。还可以实现接口 IF_ABAP_TIMER_HANDLER 将 ABAP 守护程序类转换为 ABAP 计时器处理程序,从而对 ABAP 计时器事件做出反应。例如,等待某些事件或在一段时间后停止守护进程。当从 ABAP 守护进程类实例化 ABAP 守护进程时,ABAP 守护进程框架将创建 ABAP 守护进程会话。

四、创建一个简单的ABAP守护进程

现在让我们创建 ABAP 守护进程并使用 PCP 消息与它们交互。如前所述,ABAP 守护进程是扩展基类 CL_ABAP_DAEMON_EXT_BASE 的 ABAP 守护进程类的实例。因此,首先我们需要按照本教程定义类。

步骤1:创建一个新的ABAP Daemon类

第一步,创建一个 ABAP 类 ZCL_ABAP_SIMPLE_DAEMON 并将 CL_ABAP_DAEMON_EXT_BASE 设置为超类。从这个超类中,我们的守护进程将从 IF_ABAP_DAEMON_EXTENSION 接口继承不同的方法,这将允许我们响应不同的事件。现在您会看到必须重新定义的 9 个继承方法的列表。
在这里插入图片描述
图1 : 必须重新定义的 IF_ABAP_DAEMON_EXTENSION 接口的继承方法列表。

步骤2:实现ON_ACCEPT方法

在创建 ABAP 守护程序类的新实例之前,将调用其 ON_ACCEPT 方法来确定是否应启动该守护程序。它接受来自您自己的类的所有启动请求,并拒绝来自任何其他程序的所有请求。这是通过检查发起启动的调用程序来实现的。

METHOD if_abap_daemon_extension~on_accept.TRY.DATA lv_program_name TYPE program.lv_program_name = cl_oo_classname_service=>get_classpool_name( 'ZCL_ABAP_SIMPLE_DAEMON' ).IF i_context_base->get_start_caller_info( )-program = lv_program_name.e_setup_mode = co_setup_mode-accept.ELSE.e_setup_mode = co_setup_mode-reject.ENDIF.CATCH cx_abap_daemon_error." to do: for productive applications, error handling, e.g. write error log!e_setup_mode = co_setup_mode-reject.ENDTRY.
ENDMETHOD.

第三步:实现ON_START方法

要启动ABAP守护进程,需要执行ON_START方法。您可以包含一条 PCP 消息,其中包含可在 ON_START 方法中访问的任意启动参数。

在这个简单的场景中,您将通过 PCP 传递参数超时。然后,守护进程将设置一个计时器,以便在每次达到超时时显示弹出消息。计数器将用于在五个消息后停止计时器。

首先,您需要创建一些私有成员变量来存储必要的数据。将这些行添加到类的 PRIVATE SECTION 中:

private section.
DATA: mv_timeout TYPE i,mo_timer   TYPE REF TO if_abap_timer_manager,mv_counter TYPE i.

您还需要添加 IF_ABAP_TIMER_HANDLER 作为守护程序类的接口。在 ON_START 方法中,您现在可以从 PCP 检索超时值,然后启动计时器。为此,请复制以下实现:

METHOD if_abap_daemon_extension~on_start.TRY." retrieve timeout from PCP start parametersmv_timeout = i_context->get_start_parameter( )->get_field( 'timeout' )." start timer for displaying messagesmo_timer = cl_abap_timer_manager=>get_timer_manager( ).mo_timer->start_timer( i_timeout = mv_timeout i_timer_handler = me ).CATCH cx_abap_daemon_error cx_ac_message_type_pcp_error cx_abap_timer_error." to do: for productive applications, error handling, e.g. write error log!ENDTRY.
ENDMETHOD.

第四步:实现ON_TIMEOUT方法

当你的ABAP守护进程在后台运行时,当超时时间过去时,ON_TIMEOUT方法将被触发。因此,您需要为类的 PUBLIC SECTION 实现一个处理程序接口 if_abap_timer_handler。通过在类中实现以下 ON_TIMEOUT 方法,将显示使用功能模块 TH_POPUP 的弹出消息,并且计时器将重新启动五次:

METHOD if_abap_timer_handler~on_timeout." increment the loop counterADD 1 TO mv_counter." display popup messageCALL FUNCTION 'TH_POPUP'EXPORTINGclient  = sy-mandtuser    = sy-unamemessage = CONV th_popup( |Timeout triggered. Number of loops: { mv_counter }| )." restart the timer if any loops are remainingIF mv_counter < 5.TRY.mo_timer->start_timer( i_timeout = mv_timeout i_timer_handler = me ).CATCH cx_abap_timer_error." to do: for productive applications, error handling, e.g. write 
error log!ENDTRY.ENDIF.
ENDMETHOD.

当守护进程在后台持续运行时,您还可以向它发送 PCP 消息。

第5步:实现ON_MESSAGE方法

ON_MESSAGE 是一个有用的方法,守护进程通过它接收用户输入并做出响应。每次守护进程收到 PCP 消息时都会调用 ON_MESSAGE 方法。当守护进程接收到用户输入时,将弹出一个弹出对话框,该对话框显示在 SAPGUI 中。

METHOD if_abap_daemon_extension~on_message.TRY." get text from PCP messageDATA(lv_text) = i_message->get_text( )." display popupCALL FUNCTION 'TH_POPUP'EXPORTINGclient  = sy-mandtuser    = sy-unamemessage = CONV th_popup( |Message received: { lv_text }| ).CATCH cx_ac_message_type_pcp_error." to do: for productive applications, error handling, e.g. write error log!ENDTRY.
ENDMETHOD.

您必须考虑这样一个事实:只有运行守护程序的程序才能通过管理器守护程序使用该守护程序。这个想法是通过守护进程类本身创建守护进程。因此,您需要向该类添加另外 3 个方法:START、SEND 和 STOP 来管理守护进程。

第6步:实现静态方法START

这个简单的 ABAP 守护进程将通过静态方法启动。因此,您需要在守护程序类中创建一个带有两个导入参数的新方法 START:

IV_DAEMON_NAME:守护进程的名称
IV_TIMEOUT:两个连续定时器事件之间的超时时间(毫秒)

为此,请将以下代码粘贴到类定义的 PUBLIC SECTION 中:

CLASS-METHODS startIMPORTINGiv_daemon_name TYPE stringiv_timeout     TYPE iRAISINGcx_abap_daemon_errorcx_ac_message_type_pcp_error.

使用 ABAP 守护程序管理器实例化 ABAP 守护程序。此方法包装类 CL_ABAP_DAEMON_CLIENT_MANAGER 的方法 START 并启动 ABAP 守护程序类的 ABAP 守护程序。其静态方法 CL_ABAP_DAEMON_CLIENT_MANAGER=>START 需要守护程序的名称和优先级作为参数。此外,您还可以将启动参数作为 PCP 消息传递。

METHOD start." set ABAP Daemon start parametersDATA(lo_pcp) = cl_ac_message_type_pcp=>create( ).lo_pcp->set_field( i_name = 'timeout' i_value = CONV #( iv_timeout ) )." start the daemon application using the ABAP Daemon Managercl_abap_daemon_client_manager=>start(i_class_name = 'ZCL_ABAP_SIMPLE_DAEMON'i_name       = CONV #( iv_daemon_name )i_priority   = cl_abap_daemon_client_manager=>co_session_priority_lowi_parameter  = lo_pcp ).
ENDMETHOD.

检查所有调用者以确保该方法仅在相关程序和 ABAP 守护程序类中使用。已启动守护进程的 ID 会被保存以供进一步使用。如果ABAP守护进程类在启动时被接受,则返回值不是初始值。

第7步:实现静态方法SEND并运行守护进程

实现一个静态方法 SEND,它将用于向守护进程发送文本,从而触发其 ON_MESSAGE 方法。该方法需要以下导入参数:

IV_DAEMON_NAME:将接收消息的守护进程的名称。

IV_TEXT:将发送到守护程序的文本消息。

将以下代码粘贴到类定义的公共部分中。


CLASS-METHODS sendIMPORTINGiv_daemon_name TYPE stringiv_text        TYPE stringRAISINGcx_abap_daemon_errorcx_ac_message_type_pcp_error.

要将 PCP 消息发送到守护程序,您需要检索类 ZCL_ABAP_SIMPLE_DAEMON 的所有正在运行的 ABAP 守护程序实例的列表。然后,您可以将每个实例的名称与 IV_DAEMON_NAME 进行比较,并相应地发送 PCP 消息。

METHOD send." retrieve the list of ABAP Daemon instancesDATA(lt_ad_info) = cl_abap_daemon_client_manager=>get_daemon_info( i_class_name = 'ZCL_ABAP_SIMPLE_DAEMON')." create PCP message with textDATA(lo_pcp) = cl_ac_message_type_pcp=>create( ).lo_pcp->set_text( iv_text )." for each running daemon instance of this classLOOP AT lt_ad_info ASSIGNING FIELD-SYMBOL(<ls_info>)." send a message if the names matchIF iv_daemon_name = <ls_info>-name.cl_abap_daemon_client_manager=>attach( <ls_info>-instance_id )->send( lo_pcp ).ENDIF.ENDLOOP.
ENDMETHOD.

现在,您只需调用之前创建的静态 START 方法即可启动守护程序。因此,只需一行代码即可创建一个新的ABAP程序Z_ABAP_SIMPLE_DAEMON_START

REPORT Z_ABAP_SIMPLE_DAEMON_START.
zcl_ABAP_simple_daemon=>start( iv_daemon_name = 'simple_daemon' iv_timeout = 10000 ).

您应该每 10 秒看到一个弹出通知:
在这里插入图片描述

第 8 步:停止 ABAP 守护进程

您可以使用 SAPGUI 中的事务 SMDAEMON 监视所有正在运行的 ABAP 守护程序。在那里你可以看到它们的状态,检查错误,甚至重新启动,并终止它们。

要停止守护程序,请从列表中选择它,然后转至 ABAP 守护程序 > 终止守护程序。或者,您也可以创建静态 STOP 方法。因此,将其添加到类定义的公共部分:

  CLASS-METHODS stopIMPORTINGiv_daemon_name TYPE stringRAISINGcx_abap_daemon_error.

并实现方法

METHOD stop." retrieve the list of ABAP Daemon instancesDATA(lt_ad_info) = cl_abap_daemon_client_manager=>get_daemon_info( i_class_name = 'ZCL_ABAP_SIMPLE_DAEMON')." for each running daemon instance of this classLOOP AT lt_ad_info ASSIGNING FIELD-SYMBOL(<ls_info>)." stop the daemon if the names matchIF iv_daemon_name = <ls_info>-name.cl_abap_daemon_client_manager=>stop( i_instance_id = <ls_info>-instance_id ).ENDIF.ENDLOOP.
ENDMETHOD.

该方法包装了 CL_ABAP_DAEMON_CLIENT_MANAGER 类的 STOP 方法,用于停止 ABAP 守护进程。现在你可以通过执行来停止你的守护进程

zcl_ABAP_simple_daemon=>stop( iv_daemon_name = 'simple_daemon' ).

来自任何 ABAP 程序。更多示例也可以在文档中找到。

五、守护进程用例。

正如这篇博客文章中很好地解释的那样,守护进程的主要用例是处理事件或管理简单的后台活动以及频繁的定期任务,例如跟踪、日志记录、资源清理等,而不会损害 LUW(逻辑工作单元-Logical Unit of Work)。

六、结论

我希望这个分步说明可以帮助您对守护进程以及如何创建守护进程有一些了解。您还可以通过重新定义其他方法来扩展此示例,以应对系统重新启动或服务器关闭的情况。例如,当服务器关闭时,会触发开发者实现的ON_SERVER_SHUTDOWN方法。当当前 AS 实例关闭时,此方法调用帮助器方法 RELOCATE 将守护程序移动到不同的 AS 实例。

 method IF_ABAP_DAEMON_EXTENSION~ON_SERVER_SHUTDOWN.relocate( ).endmethod.

relocate 方法必须从当前 AS ABAP 的列表中随机选择一个 AS 实例。然后,该应用程序服务器用作启动当前 ABAP 守护程序类的守护程序的目标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/724006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「滚雪球学Java」:GUI编程(章节汇总)

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Kosmos-1: 通用接口架构下的多模态大语言模型

Kosmos-1: 通用接口架构下的多模态大语言模型 FesianXu 20230513 at Baidu Search Team 前言 在大规模语言模型&#xff08;Large Language Model, LLM&#xff09;看似要带来新一番人工智能变革浪潮之际&#xff0c;越来越多尝试以LLM作为通用接口去融入各种任务的工作&#…

【vue】ant-design弹出框无法关闭和runtimecore提示isFucntion is not function的问题修复

【vue】ant-design弹出框无法关闭和runtimecore提示isFucntion is not function的问题修复&#xff0c;初步分析是vue发布3.4版本以后引起的兼容性问题。 问题截图&#xff1a; 1.isFucntion is not function&#xff0c;是由于vue升级后众多插件版本不匹配造成的问题 2.弹框…

计算机中msvcp140.dll,丢失怎么修复与解决

一、msvcp140.dll20个软件环境 msvcp140.dll文件是许多软件运行环境的组成部分&#xff0c;通常与Microsoft Visual C Redistributable关联。以下是可能使用该文件的软件环境&#xff1a; 微软办公软件&#xff1a;如Microsoft Office套件&#xff0c;包括Word、Excel、Power…

Python给图片加水印

受到“手动给证件加文字太麻烦”的感触&#xff0c;想用Python来实现给图片加水印&#xff0c;这不方便多了。 这里使用PIL模块&#xff1a; from PIL import Image from PIL import ImageFont from PIL import ImageDrawimg_t Image.open(cat.jpg) img_size_t img_t.size…

OJ:循环队列

622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 思路 思路&#xff1a;首先循环队列的意思是&#xff1a;空间固定&#xff0c;就是提前开辟好&#xff0c;满了就不能插入了&#xff0c;但是删除数据后仍有空间&#xff0c;删除循环队列里面的数据后&#xff0c;保…

Apache ECharts数据可视化技术

介绍 官方地址:Apache ECharts 快速入门案例echarts.init //初始化方法 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><script src"echart…

基于JavaWEB SpringBoot婚纱影楼摄影预约网站设计和实现

基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…

Java Swing游戏开发学习8

内容来自RyiSnow视频讲解 上一节提到的bug&#xff0c;不知道有没有人发现&#xff1f; 在播放音乐和音效的时候使用的是同一个clip对象&#xff0c;播放背景音乐在前&#xff0c;后续播放音效&#xff0c;clip对象就被覆盖了&#xff0c;因此导致调用停止播放背景音乐的时候&a…

计算机组成原理之机器:总线

计算机组成原理之机器 笔记来源&#xff1a;哈尔滨工业大学计算机组成原理&#xff08;哈工大刘宏伟&#xff09; Chapter2&#xff1a;总线 2.1 总线的基本概念 1.为什么需要总线&#xff1f;有几百个部件需要连接进行信息传输 2.什么是总线&#xff1f;总线是连接各个部件…

七、链表问题(上)

160、相交链表&#xff08;简单&#xff09; 题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个…

如何选择阿里云服务器配置?(CPU/内存/带宽/磁盘)

阿里云服务器配置怎么选择&#xff1f;CPU内存、公网带宽和系统盘怎么选择&#xff1f;个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例&#xff0c;企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器&#xff0c;阿里云服务器网aliyunfuwuqi.com整…

对象得定义与使用(动力节点老杜)

对象思想 1.什么是面向过程&#xff0c;什么是面向对象&#xff1f; 换而言之&#xff0c;面向对象思想实际就是将整体分成一个个独立的单元&#xff0c;每个单元都有自己得任务和属性&#xff0c;所有单元结合在一起完成一个整体。如果某个单元出现了问题还可以及时处理&…

比肩Gen-2,全新开源文生视频模型

著名开源平台Stability.ai在官网宣布&#xff0c;推出全新文生视频的扩散模型Stable Video Diffusion&#xff0c;已开源了该项目并公布了论文。 据悉&#xff0c;用户通过文本或图像就能生成高精准&#xff0c;14帧和25帧的短视频。目前&#xff0c;Stable Video Diffusion处…

回溯算法02-组合总合III(Java)

2.组合总合III 题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3,…

[Linux]如何理解kernel、shell、bash

文章目录 概念总览kernelshell&bash 概念总览 内核(kernel) &#xff0c;外壳(shell) &#xff0c;bash kernel kernel是指操作系统中的核心部分&#xff0c;用户一般是不能直接使用kernel的。它主要负责管理硬件资源和提供系统服务&#xff0c;如内存管理、进程管理、文件…

Pytest测试技巧之Fixture:模块化管理测试数据!

在 Pytest 测试中&#xff0c;有效管理测试数据是提高测试质量和可维护性的关键。本文将深入探讨 Pytest 中的 Fixture&#xff0c;特别是如何利用 Fixture 实现测试数据的模块化管理&#xff0c;以提高测试用例的清晰度和可复用性。 什么是Fixture&#xff1f; 在 Pytest 中…

【考研数学】武忠祥各阶段用书搭配+学习包

25考研数学全流程规划&#xff01;别等到二战了才知道这样学 本人属于基础很差相当于是零基础的考研党&#xff0c;经过一年备考成功上岸 中间花费了很多时间在考研数学备考信息检索上&#xff0c;写下这篇希望能帮助基础不好的学弟学妹们多节约一些时间复习&#xff01; 25…

【PowerMockito:编写单元测试过程中原方法没有注入的属性在跑单元测试时出现空指针】

出错场景 下面这一步报空指针&#xff0c;但是因为没有注入&#xff0c;在测试类中无法使用Mock 解决 在执行方法前&#xff0c;加入以下代码 MemberModifier.field(ResourceServiceImpl.class,"zero").set(resourceService,"0");

网页打开慢,这锅该谁背?

一、背景 工作中扯皮说不可避免且非常常见的事情. 开发与产品、开发和测试、前端和后端都会产生扯皮现象。今天要聊的一个问题就是前后端之间的扯皮问题。 网页打开太慢或者点击了某个按钮发现数据很久才显示出来&#xff0c;这个锅谁背? 做开发不能无凭据地胡乱甩锅, 我们…