当前位置: 首页 > article >正文

Express 集成Sequelize+Sqlite3 默认开启WAL 进程间通信 Conf 打包成可执行 exe 文件

代码:express-exe: 将Express开发的js打包成exe服务丢给客户端使用

实现目标

  1. Express 集成 Sequelize 操作 Sqlite3 数据库;

  2. 启动 Sqlite3 时默认开启 WAL 模式,避免读写互锁,支持并发读;

  3. 利用 Conf 实现主进程与 Express 服务的底层通信;

  4. 打包成可执行文件,在 mac 和 windows 两套系统中均可使用;

Express 集成 Sequelize

  1. Express 在启动时,会检查所有可能的 require 类库,并将该类库实例化,作为单例方式向外导出使用

  2. 这样包括一些类库引入时需要前置构建的工作,即可交给启动函数来执行,执行完毕后,再对外抛出

  3. 遇到异步类函数比较难操作,传统的 commonJS 没有顶层 await,实现等待处理比较麻烦

  4. createModel 函数无需 async/await 化,虽然能保证模型 findAll 之前必然完成 wal 和 sync,但实际操作是主进程以子进程方式先启动 http 服务,之后才开始运行主渲染进程 和 webview 进程,两者产生并发性操作几乎为 0,因此无需耗费心思在每次 User 使用前都等待 db 的统一化操作

  5. Model 只是一种映射类 和 db 链接是两个概念,前者存在的意义是实现 sql 语句拼接的函数化以及返回 sql 的对象化填充时有个 Map 对应,sequelize 才是将 Model 转化的 sql 语句拿去执行的人

    1. 因此,我们可以集中管理 sequelize,封装一个 sequelize 收集类专门收集所有的 db 连接,等服务关闭时,统一关闭 db 链接

以下就是上面实现的具体代码,分为 userModel.js,instanceModel.js,sequelizeCollector.js 三个文件

// userModel.js
// src/models/userModel.js
const { DataTypes } = require('sequelize');
const { createModel } = require('./instanceModel');const { Model, sequelize } = createModel('User', {id: {type: DataTypes.INTEGER,autoIncrement: true,primaryKey: true,},name: {type: DataTypes.STRING,allowNull: false,},email: {type: DataTypes.STRING,allowNull: false,unique: true,},
});module.exports = { User: Model, sequelize };// instanceModel.js
// src/models/instanceModel.js
const sequelizeCollector = require("../db/sequelizeCollector");function createModel(modelName, attributes, options = {}) {// Get Sequelize instance from collectorconst sequelize = sequelizeCollector.getInstance(modelName);// 定义模型const Model = sequelize.define(modelName, attributes, {tableName: modelName.toLowerCase(),freezeTableName: true,timestamps: true,...options,});// 同步模型到数据库(创建表)Model.sync({ force: false }).then(() => {console.log(`${modelName} table synchronized`);}).catch((err) => {console.error(`Failed to sync ${modelName} table:`, err);});return { Model, sequelize };
}module.exports = { createModel };// sequelizeCollector.js
const { Sequelize } = require('sequelize');
const path = require('path');
const ConfigManager = require("../config/ConfManager");class SequelizeCollector {constructor() {this.connections = new Map(); // Using Map to store modelName -> sequelize instancethis.configManager = new ConfigManager({ configName: "starter.http", configPath: "./config" });}// 添加 Sequelize 连接addConnection(modelName, sequelizeInstance) {if (sequelizeInstance && typeof sequelizeInstance.close === 'function') {this.connections.set(modelName, sequelizeInstance);console.log(`Sequelize connection added for model: ${modelName}`);}}// 获取或创建 Sequelize 实例getInstance(modelName) {// Check if instance already existsif (this.connections.has(modelName)) {return this.connections.get(modelName);}// Create new Sequelize instance if it doesn't existconst dbPath = path.join(this.configManager.get("dbPath"), '/sqlite', `${modelName.toLowerCase()}.db`);const sequelize = new Sequelize({dialect: 'sqlite',storage: dbPath,logging: false,});// Enable WAL modesequelize.query('PRAGMA journal_mode = WAL;').then(() => {console.log(`WAL mode enabled for database: ${dbPath}`);}).catch((err) => {console.error(`Failed to enable WAL mode for ${dbPath}:`, err);});// Add to connectionsthis.addConnection(modelName, sequelize);return sequelize;}// 移除 Sequelize 连接removeConnection(modelName) {if (this.connections.has(modelName)) {this.connections.delete(modelName);console.log(`Sequelize connection removed for model: ${modelName}`);}}// 关闭所有 Sequelize 连接async closeAllConnections() {const closePromises = Array.from(this.connections.entries()).map(async ([modelName, sequelize]) => {try {await sequelize.close();this.connections.delete(modelName);console.log(`Sequelize connection closed for model: ${modelName}`);} catch (error) {console.error(`Error closing Sequelize connection for ${modelName}:`, error);}});await Promise.all(closePromises);}// 获取当前连接数量getConnectionCount() {return this.connections.size;}
}// 单例模式
const sequelizeCollector = new SequelizeCollector();module.exports = sequelizeCollector;// userService.js
// services/userService.js
const formatUtils = require('../utils/format'); // 引入工具模块
const {User} = require('../models/userModel');// 获取所有用户
async function getUsers() {try {/*** 下面注释的代码是将 createModel 函数 async/await* 这种方式可保证 wal 和 sync 均完成的后再执行 findAll* 但考虑现实情况, wal 和 sync 操作不需要 await* 因为是单步操作 协程调度下 单步操作基本为交替操作* wal 和 sync 距离很近 操作可在 findAll 前完成* 从输出的 console 也能判断该结论* 此外 因为主渲染进程 和 webview 都在 http 启动之后才开始运行* 所以 wal 和 sync 异步操作没有任何影响* 在协程逻辑下 sync 操作不会和 findAll 同时存在* 因此 sync 理论上会先执行后再执行 findAll*/// const {User, sequelize} = await UserPromise;// console.log(User)const users = await User.findAll();return users.map(user => ({...user.toJSON(),name: formatUtils.capitalize(user.name),email: formatUtils.capitalize(user.email),createdAt: formatUtils.formatDate(user.createdAt),}));} catch (error) {throw new Error(`Error fetching users: ${error.message}`);}
}

打成可执行文件

  1. 利用 windows 的 wsl,运行在 centos 系统中

    1. CentOS7 的类库不支持 node18 版本,会报类库错误

升级为 CentOS8 会遇到以下问题

wsl centos8 二进制安装文件

https://github.com/wsldl-pg/CentWSL/releases

除了将基本镜像更换为腾讯云,还要把下面截图的两个文件里面的镜像更换为腾讯云

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos8_base.repo
CentOS8 需要额外更改两个文件

解决阿里云CentOS8 yum安装appstream报错,更新yum后无法makecache的问题_errors during downloading metadata for repository -CSDN博客

搞定镜像后,要安装开发包,否则报prebuild-install 错误,这样在pkg . 打包时就不会报prebuild-install错误了

dnf groupinstall -y "Development Tools"
dnf install -y python3 python3-devel
yum install -y python39
echo "alias python3=/usr/bin/python3.9" >> ~/.bashrc
source ~/.bashrc

macos 打包直接双击运行问题

  1. 双击运行默认路径是 /User/xxx 用户根目录,必须到指定路径,使用 ./pkg-express 方式运行,才能正确寻找路径

  2. 因此需要使用绝对路径更好

注意

  1. 切换不同平台时,需要运行 npm rebuild,否则是没有这个平台的二进制的,即使都能打包出来对应的可执行文件,但不可运行

相关文章:

Express 集成Sequelize+Sqlite3 默认开启WAL 进程间通信 Conf 打包成可执行 exe 文件

代码:express-exe: 将Express开发的js打包成exe服务丢给客户端使用 实现目标 Express 集成 Sequelize 操作 Sqlite3 数据库; 启动 Sqlite3 时默认开启 WAL 模式,避免读写互锁,支持并发读; 利用 Conf 实现主进程与 Ex…...

CppCon 2015 学习:A C++14 Approach to Dates and Times

Big Picture — 日期库简介 扩展 标准库 这个库是对 C 标准库中 <chrono> 的自然延伸&#xff0c;专注于处理“日历”相关的功能&#xff08;比如年月日、闰年、节假日等&#xff09;&#xff0c;而不仅仅是时间点和时长。极简设计 它是**单头文件&#xff08;header-on…...

基于CNN的OFDM-IM信号检测系统设计与实现

基于CNN的OFDM-IM信号检测系统设计与实现 摘要 本文详细研究了基于卷积神经网络(CNN)的正交频分复用索引调制(OFDM-IM)信号检测方法。通过在不同信噪比(SNR)和信道条件下进行系统仿真,对比分析了CNN检测器与传统最大似然(ML)检测器的误码率(BER)性能和计算复杂度。实验结果表…...

macos常见且应该避免被覆盖的系统环境变量(避免用 USERNAME 作为你的自定义变量名)

文章目录 macos避免用 USERNAME 作为你的自定义变量名macos常见且应该避免被覆盖的系统环境变量 macos避免用 USERNAME 作为你的自定义变量名 问题&#xff1a; 你执行了&#xff1a;export USERNAME“admin” 然后执行&#xff1a;echo ${USERNAME} 输出却是&#xff1a;xxx …...

2024年认证杯SPSSPRO杯数学建模D题(第二阶段)AI绘画带来的挑战解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现&#xff1a; 2023 年开年&#xff0c;ChatGPT 作为一款聊天型AI工具&#xff0c;成为了超越疫情的热门词条&#xff1b;而在AI的另一个分支——绘图领域&#xff0c;一款名为Midjourney&#xff08;MJ&#xff…...

深入理解CSS常规流布局

引言 在网页设计中&#xff0c;理解元素如何排列和相互作用至关重要。CSS提供了三种主要的布局方式&#xff1a;常规流、浮动和定位。本文将重点探讨最基础也是最常用的常规流布局&#xff08;Normal Flow&#xff09;&#xff0c;帮助开发者掌握页面布局的核心机制。 什么是…...

DOCKER使用记录

1、拉取镜像 直接使用docker pull <image>&#xff0c;大概率会出现下面的报错信息&#xff1a; (base) jetsonyahboom:~$ docker pull ubuntu:18.04 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while …...

MYSQL中常见的函数和使用

字符串函数 CONCAT(str1,str2,...,strN) &#xff1a;用于将多个字符串连接成一个字符串。例如&#xff0c;SELECT CONCAT(SQL, , 函数) &#xff0c;结果为 “SQL 函数”。 LOWER(str) &#xff1a;将字符串中的所有字母转换为小写。例如&#xff0c;SELECT LOWER(MySQL Fun…...

【深度学习相关安装及配环境】Anaconda搭建虚拟环境并安装CUDA、cuDVV和对应版本的Pytorch,并在jupyter notebook上部署

目录 1. 查看自己电脑的cuda版本2.安装cuda关于环境变量的配置测试一下&#xff0c;安装完成 3.安装cuDVV环境变量的配置测试一下&#xff0c;安装完成 4.创建虚拟环境先安装镜像源下载3.11版本py 5.在虚拟环境下&#xff0c;下载pytorch6.验证是否安装成功7.在jupyter noteboo…...

web3-区块链基础:从区块添加机制到哈希加密与默克尔树结构

区块链基础&#xff1a;从区块添加机制到哈希加密与默克尔树结构 什么是区块链 抽象的回答: 区块链提供了一种让多个参与方在没有一个唯一可信方的情况下达成合作 若有可信第三方 > 不需要区块链 [金融系统中常常没有可信的参与方] 像股票市场&#xff0c;或者一个国家的…...

TCP小结

1. 核心特性 面向连接&#xff1a;通过三次握手建立连接&#xff0c;四次挥手终止连接&#xff0c;确保通信双方状态同步。 TCP连接建立的3次握手 抓包&#xff1a; client发出连接请求&#xff1b; server回应client请求&#xff0c;并且同步发送syn连接&#xff1b; clien…...

django ssh登录 并执行命令

在Django开发环境中&#xff0c;通常不推荐直接通过SSH登录到服务器并执行命令&#xff0c;因为这违背了Django的架构设计原则&#xff0c;即前端与后端分离。Django主要负责处理Web请求、逻辑处理和数据库交互&#xff0c;而不直接执行系统级命令。然而&#xff0c;在某些情况…...

unix/linux,sudo,其高级使用

掌握了sudo的基石,现在是时候向更高阶的技巧和应用进发了!sudo的强大远不止于简单的sudo <command>。它的高级用法能让你在复杂的系统管理和安全场景中游刃有余,如同经验丰富的物理学家巧妙运用各种定律解决棘手问题。 sudo 的高级使用技巧与场景 精细化命令控制与参…...

Python 打包指南:setup.py 与 pyproject.toml 的全面对比与实战

在 Python 开发中&#xff0c;创建可安装的包是分享代码的重要方式。本文将深入解析两种主流打包方法——setup.py 和 pyproject.toml&#xff0c;并通过一个实际项目示例&#xff0c;展示如何使用现代的 pyproject.toml 方法构建、测试和发布 Python 包。 一、setup.py 与 pyp…...

计算机视觉与深度学习 | 基于OpenCV的实时睡意检测系统

基于OpenCV的实时睡意检测系统 下面是一个完整的基于OpenCV的睡意检测系统实现,该系统使用眼睛纵横比(EAR)算法检测用户是否疲劳或瞌睡。 import cv2 import numpy as np import dlib from scipy.spatial import distance as dist import pygame import time# 初始化pygame用…...

python打卡day44@浙大疏锦行

知识点回顾&#xff1a; 预训练的概念常见的分类预训练模型图像预训练模型的发展史预训练的策略预训练代码实战&#xff1a;resnet18 作业&#xff1a; 尝试在cifar10对比如下其他的预训练模型&#xff0c;观察差异&#xff0c;尽可能和他人选择的不同尝试通过ctrl进入resnet的…...

性能优化 - 案例篇:缓存_Guava#LoadingCache设计

文章目录 Pre引言1. 缓存基本概念2. Guava 的 LoadingCache2.1 引入依赖与初始化2.2 手动 put 与自动加载&#xff08;CacheLoader&#xff09;2.2.1 示例代码 2.3 缓存移除与监听&#xff08;invalidate removalListener&#xff09; 3. 缓存回收策略3.1 基于容量的回收&…...

NiceGUI 是一个基于 Python 的现代 Web 应用框架

NiceGUI 是一个基于 Python 的现代 Web 应用框架&#xff0c;它允许开发者直接使用 Python 构建交互式 Web 界面&#xff0c;而无需编写前端代码。以下是 NiceGUI 的主要功能和特点&#xff1a; 核心功能 1.简单易用的 UI 组件 提供按钮、文本框、下拉菜单、滑块、图表等常见…...

生动形象理解CNN

好的&#xff01;我们把卷积神经网络&#xff08;CNN&#xff09;想象成一个专门识别图像的“侦探小队”&#xff0c;用破案过程来生动解释它的工作原理&#xff1a; &#x1f575;️♂️ 案件&#xff1a;识别一张“猫片” 侦探小队&#xff08;CNN&#xff09;的破案流程&am…...

python入门(1)

第一章 第一个python程序 1.1 print函数 print方法的作用 : 把想要输出的内容打印在屏幕上 print("Hello World") 1.2 输出中文 在Python 2.x版本中&#xff0c;默认的编码方式是ASCII编码方式&#xff0c;如果程序中用到了中文&#xff0c;直接输出结果很可能会…...

【PDF提取表格】如何提取发票内容文字并导出到Excel表格,并将发票用发票号改名,基于pdf电子发票的应用实现

应用场景 该应用主要用于企业财务部门或个人处理大量电子发票&#xff0c;实现以下功能&#xff1a; 自动从 PDF 电子发票中提取关键信息&#xff08;如发票号码、日期、金额、销售方等&#xff09;将提取的信息整理并导出到 Excel 表格&#xff0c;方便进行财务统计和报销使…...

Hugging Face 最新开源 SmolVLA 小模型入门教程(一)

系列文章目录 目录 系列文章目录 前言 一、引言 二、认识 SmolVLA&#xff01; 三、如何使用SmolVLA&#xff1f; 3.1 安装 3.2 微调预训练模型 3.3 从头开始训练 四、方法 五、主要架构 5.1 视觉语言模型&#xff08;VLM&#xff09; 5.2 动作专家&#xff1a;流匹…...

封闭内网安装配置VSCode Anconda3 并配置 PyQt5开发

封闭内网安装配置VSCode Anconda3 并配置 PyQt5开发 零一 vscode1.1 下载 vscode1.2 下载插件1.3 安装 二 anaconda 32.1 下载2.2 新建虚拟环境1 新建快捷方式,启动base2 新建虚拟环境 3 配置Qt designer3.1 designer.exe和uic.exe3.2 设置插件,3.4 ui文件转为py文件 4使用4.1 …...

大话软工笔记—组合要素2之逻辑

1. 逻辑的概念 逻辑&#xff0c;指的是思维的规律和规则&#xff0c;是对思维过程的抽象。 结合逻辑的一般定义以及信息系统的设计方法&#xff0c;对逻辑的概念进行抽提、定义为三个核心内涵&#xff0c;即&#xff1a;规律、顺序、规则。 &#xff08;1&#xff09;规律&a…...

浅谈边缘计算

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…...

宝塔专属清理区域,宝塔清理MySQL日志(高效释放空间)

1. 删除超过 365 天的积分变更记录 宝塔面板 → 数据库 → 选择数据库 → 点击 管理 进入 phpMyAdmin 后&#xff1a; 选择在用的数据库名 看到顶部的 SQL 点击 输入命令 然后点击执行 DELETE FROM pre_common_credit_log WHERE dateline < UNIX_TIMESTAMP(DATE_SUB(NO…...

7.Demo Js执行同步任务,微任务,宏任务的顺序(3)

一个包含 同步任务、微任务&#xff08;Promise&#xff09;、宏任务&#xff08;setTimeout&#xff09; 的例子&#xff0c;JS 是怎么调度这些任务的。 &#x1f3af; 例子代码&#xff08;建议复制到浏览器控制台运行&#xff09; console.log(‘同步任务 1’); setTimeo…...

边缘计算网关赋能沸石转轮运行故障智能诊断的配置实例

一、项目背景 在环保行业&#xff0c;随着国家对大气污染治理要求的不断提高&#xff0c;VOCs废气处理成为了众多企业的重要任务。沸石转轮作为一种高效的VOCs治理设备&#xff0c;被广泛应用于石油化工、汽车制造、印刷包装等主流行业。这些行业生产规模大、废气排放量多&…...

机器学习之深入理解机器学习常见算法:原理、公式与应用

机器学习之深入理解机器学习常见算法:原理、公式与应用 机器学习是一门让计算机自动从数据中学习规律的技术体系。常见的机器学习算法可以分为监督学习、无监督学习和深度学习三大类。本文将系统介绍每类中具有代表性的算法,并深入剖析其核心原理与数学基础。 一、监督学习(…...

Python实例题: Python 的简单电影信息

目录 Python实例题 题目 代码实现 实现原理 网页请求&#xff1a; 内容解析&#xff1a; 数据存储&#xff1a; 反爬策略&#xff1a; 关键代码解析 1. 网页请求处理 2. 电影列表解析 3. 电影详情解析 4. 爬虫主逻辑 使用说明 安装依赖&#xff1a; 修改配置&a…...