Skip to content

一个面向控制面、管理面的业务框架。

Notifications You must be signed in to change notification settings

yanxicheung/cpa_demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

概述:

cpa_demo是一个面向控制面、管理面的业务框架。

cpa_demo使用单进程多线程模型,一个业务模块在代码上对应一个entry,从程序运行的角度,对应一个线程。

各个业务模块之间的通信使用消息队列,每个业务模块都有一个instkey,作为模块间通信的标识。

cpa_demo适合使用消息驱动的应用场景。

进程间的通信目前暂时没有支持,优先考虑使用TCP或者HTTP

代码结构:

cpa_demo的物理设计如下:

.
├── build.sh
├── CMakeLists.txt
├── include
│   ├── CtrlFoo.h
│   ├── infra
│   │   ├── base
│   │   │   ├── BlockingQueue.h
│   │   │   ├── Callbacks.h
│   │   │   ├── Condition.h
│   │   │   ├── CountDownLatch.h
│   │   │   ├── Mutex.h
│   │   │   ├── Noncopyable.h
│   │   │   ├── Thread.h
│   │   │   └── TimerWheel.h
│   │   ├── log
│   │   └── oss
│   │       ├── Cleaner.h
│   │       ├── Executor.h
│   │       ├── Msg.h
│   │       ├── MsgQueue.h
│   │       ├── OSSDef.h
│   │       ├── OSS.h
│   │       └── OSSTimer.h
│   └── pb
│       ├── movie.pb.h
│       └── movie.proto
├── README.md
└── source
    ├── CtrlFoo.cpp
    ├── entry1.cpp
    ├── entry2.cpp
    ├── infra
    │   ├── base
    │   │   ├── Thread.cpp
    │   │   └── TimerWheel.cpp
    │   ├── log
    │   └── oss
    │       ├── Cleaner.cpp
    │       ├── Executor.cpp
    │       ├── Msg.cpp
    │       ├── MsgQueue.cpp
    │       ├── OSS.cpp
    │       └── OSSTimer.cpp
    ├── main.cpp
    └── pb
        └── movie.pb.cc

build.sh为一键编译、运行脚本。

框架代码位于infra目录下,其中base目录下提供了系统编程常用的工具,包括队列、条件变量、互斥锁、线程、定时器、coutdownLatch

OSS接口:

上层业务模块使用OSS只需要包含OSS.h

OSS提供的接口,具备线程安全性。对上层业务提供如下接口:

OSS_Init

void OSS_Init(); // 系统初始化

OSS系统初始化,在最开始的时候调用一次。

OSS_UserRegist

struct ObserverConfig
{
    EntryCallback entry;
    const char* instKey;   // 内部通信使用的key
};

Handle OSS_UserRegist(const ObserverConfig& config);

将业务模块注册到OSS,注册后OSS会为业务模块分配消息队列、线程资源。

返回句柄HandleHandle代表OSS为业务模块分配的资源。

Handle值一定要用一个变量保存,否则分配的资源将被自动释放,无法使用。

手动释放资源调用OSS_UserUnregist

一个业务模块的消息入口要满足如下形式:

typedef function<void (int state, int eventid, void *msg, int msgLen, void* data)> EntryCallback;

支持两种风格消息入口的注册:

  1. C语言风格接口。
  2. 类的成员函数。

使用示例:

Handle regist(const char*key, const EntryCallback& cb)
{
    ObserverConfig config =
    {
        .entry = cb,
        .instKey = key
    };
    return OSS_UserRegist(config);
}

int main(int argc, char **argv)
{
    OSS_Init();
    Handle h1 = regist("entry1", DemoEntry1);
    Handle h2 = regist("entry2", DemoEntry2);
    Handle h3 = regist("foo", std::bind(&CtrlFoo::Entry, make_shared<CtrlFoo>(), _1, _2, _3, _4, _5));
    int cnt = 0;
    while (1)
    {
        cnt++;
        sleep(1);
        if(cnt == 10)  // release
        {
            OSS_UserUnregist(h1);
            OSS_UserUnregist(h2);
            OSS_UserUnregist(h3);
        }
    }
    return 0;
}

OSS_UserUnregist

void OSS_UserUnregist(Handle& handle);

参数值为OSS_UserRegist的返回值,调用后由OSS释放handle对应的资源(线程、消息队列)。

OSS_Send

void OSS_Send(const char* instKey, int eventId, const void* msg, int msgLen);

发送消息接口,其中instKey作为对端模块标标识,在消息入口注册时指定。

OSS_SetLoopTimer

void OSS_SetLoopTimer(uint8_t timerNo, uint32_t duration);

设置循环定时器,timerNo为定时器标识,duration为定时器长度。

timerNo对应的定时器超时后,会发送一条超时消息,timerNo和超时消息的映射关系见OSSDef.h

OSS_SetRelativeTimer

void OSS_SetRelativeTimer(uint8_t timerNo, uint32_t duration);

设置相对定时器,仅被触发一次,timerNo为定时器标识,duration为定时器长度。

其他:

示例中,模块entry1entry2使用protobuf演示了消息的发送和处理,如需运行demo请安装protobuf

movie.protoprotobuf消息定义文件,movie.pb.hmovie.pb.ccprotobuf编译器自动生成。

模块CtrlFoo演示了定时器的使用。

About

一个面向控制面、管理面的业务框架。

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published