一日一技:如何实现一个轻量插件系统

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 一日一技:如何实现一个轻量插件系统

摄影:产品经理非常贵的牛肉就这么一丁点

假设我们实现了一个程序,它从 Redis 读取数据,然后写入 MongoDB。一开始程序是这样的:


def read_from_redis():    ...
def write_to_mongodb(doc):    ...
def parse():    for doc in self.read_from_redis():        self.write_to_mongodb(doc)

for doc in self.read_from_redis()的循环中,每次循环返回的是一个字典,这个字典包含很多项,例如agedate等等。我们需要设计一些逻辑对这个数据进行处理或者过滤。

但这些逻辑是逐渐增加,一开始只有一个需求,就是如果发现docage字段中,如果age不是数字且不能转换为数字,那么需要把它改成N/A

后来又增加了一个新的需求,如果doc里面的date字段对应的日期小于2020-05-01,那么这条数据直接丢弃。

接下来还要新增很多其他的需求。为了避免反复修改代码,我们可以实现一个轻量级的插件系统。

我们先实现调用这个插件系统的部分:


plugins = {}
def read_from_redis():    datas = [        {'age': 34, 'name': 'xxx', 'date': '2020-05-10'},        {'age': 12, 'name': 'yyy', 'date': '2020-04-03'},        {'age': '23', 'name': 'zzz', 'date': '2020-05-12'},        {'age': 'aa', 'name': 'abc', 'date': '2020-05-10'},        {'age': 89, 'name': 'def', 'date': '2020-02-10'},        {'age': '', 'name': 'xyz', 'date': '2020-05-10'},        {'age': 'xy', 'name': 'xxx', 'date': '2020-05-10'},        {'age': 'mp', 'name': 'xxx', 'date': '2020-05-10'},        {'age': 34, 'name': 'xxx', 'date': '2019-02-10'},    ]    for data in datas:        yield data
def write_to_mongodb(doc):    print(f'正在把数据:{doc} 写入到 MongoDB 中')
def parse():    for doc in read_from_redis():        for name, plugin in plugins.items():            print(f'正在运行插件:{name}')            doc = plugin(doc)            if not doc:                print(f'数据: {doc},被插件:{name}过滤。')            continue        write_to_mongodb(doc)
if __name__ == '__main__':    parse()

看到这里,你会不会觉得很奇怪,这里的plugins不是一个空字典吗?那你下面的 for 循环怎么能够执行呢?

不慌,我们现在使用装饰器把插件注册plugins中:

def register(plugin):    plugins[plugin.__name__] = plugin    return plugin
@registerdef transfer_age_to_int(doc):    try:        doc['age'] = int(doc['age'])    except ValueError:        doc['age'] = 'N/A'    return doc
@registerdef filter_date(doc):    date = doc['doc']    if date < '2020-05-01':        return None    return doc

这个装饰器,它的作用就是把它装饰的函数存到plugins字典中。所以当我们使用装饰器装饰一个 plugin 函数的时候,它就已经被自动注册到plugins字典中了。不需要我们再手动存放一次。

下面我们来实际运行一下:

可以看到,不是数字且不能被转换为数字的age字段的值被改成了N/Adate小于2020-05-01的数据就直接丢弃了。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7月前
|
消息中间件 Java 数据库
【消息队列开发】 实现 VirtualHostTests 类——测试虚拟主机操作
【消息队列开发】 实现 VirtualHostTests 类——测试虚拟主机操作
|
消息中间件 数据可视化 Java
Linxu下RocketMq及可视化界面的搭建
Linxu下RocketMq配置信息及可视化界面的搭建
751 0
|
5月前
|
Kubernetes jenkins 持续交付
微服务从代码到k8s部署应有尽有系列(十四、部署环境搭建)
微服务从代码到k8s部署应有尽有系列(十四、部署环境搭建)
|
6月前
|
消息中间件 Java 中间件
如何在Java项目中实现高效的消息队列系统
如何在Java项目中实现高效的消息队列系统
|
8月前
|
Android开发 开发者 Kotlin
FragmentFactory :功能详解&使用场景
FragmentFactory :功能详解&使用场景
173 0
|
网络协议 前端开发 物联网
【实践】高性能PHP应用容器workerman快速入门
workerman是一款开源高性能PHP应用容器,它大大突破了传统PHP应用范围,被广泛的用于互联网、即时通讯、APP开发、硬件通讯、智能家居、物联网等领域的开发。他是纯php实现的,跟swoole不一样,Swoole 是一个使用 C++ 语言编写的基于异步事件驱动和协程的并行网络通信引擎,对比来看workerman对PHPer更加友好,入门门槛更低,而且跨平台性更好,和已有的项目的对接更简单,更快速。因为它本身是PHP编写的,所以只要服务器支持php运行几乎就可以支持workerman的使用,无需更换运行环境或者对代码或者框架进行大幅的修改。集成到常见的框架比如thinkphp、larave
893 1
|
弹性计算 开发框架 Ubuntu
利用阿里云轻量服务器进行网页部署
在学校图书馆自习室仅可以线下进行入室签到,遂有想法进行服务器部署网页进行签到
利用阿里云轻量服务器进行网页部署
|
存储 Web App开发 监控
模拟微信第一篇,nodejs搭建一套高性能分布式的在线文件服务
模拟微信第一篇,nodejs搭建一套高性能分布式的在线文件服务。深度好文实战好文连载:手把手教对象从零开始,开发一款社交通讯APP
326 0
模拟微信第一篇,nodejs搭建一套高性能分布式的在线文件服务
|
自然语言处理 JavaScript 前端开发
从零打造一款轻量且天然支持SSR的CMS系统——simpleCMS
2年前笔者开发了一款基于 nodejs 的全栈开源 cms 系统 XPCMS, 主要是为了解决技术开发者搭建自身内容平台的局限以及降低使用成本, 虽然1.0版本已经完成, 但是从整体部署和二次开发的便捷度上还是存在很多缺点, 更加适合有一定技术能力的开发者来使用. 为了解决 XPCMS 的不足, 去年笔者和朋友特地开发了一款轻量便捷的内容管理系统——simpleCMS, 目前已在 github 上开源, 且能同时适配PC端和移动端.
457 0
|
消息中间件 数据可视化 Kafka
RocketMQ 可视化环境搭建和基础代码使用(上)
RocketMQ 可视化环境搭建和基础代码使用(上)
865 0
RocketMQ 可视化环境搭建和基础代码使用(上)