简单的 schdule Nodejs 脚本在连接到远程数据库时插入记录两次

2024-03-27

我有一个时间表nodejs脚本。基本上,它有时间表和命令表。调度表有很多命令行。 Nodejs 脚本每 5 秒检查一次调度表。如果预定时间与当前时间匹配。我将命令行(从计划表)插入到命令表中。

错误是

我在笔记本电脑上运行脚本并进行测试数据库的本地副本在我的笔记本电脑上。 Asingle仅插入计划表中的命令once.

我在笔记本电脑上运行脚本并进行测试RDS(远程mysql服务器)在我的笔记本电脑上。 Asingle仅插入计划表中的命令twice,但其中之一,SchduleId 是null. (为什么 ScheduleId 为 NULL?)

完整代码

var config = require("./config.js");
var Promise = require('bluebird');
var mysql = require('promise-mysql');
var ON_DEATH = require('death');


var g_pool = null;

function connect_db() {
  g_pool = mysql.createPool(config.db_config);
}


function close_db() {
  g_pool.end(function (err) {
    // all connections in the pool have ended
    });
}



// http://thecodeship.com/web-development/alternative-to-javascript-evil-setinterval/
function interval(func, wait, times){
    var interv = function(w, t) {
    return function() {
        if(typeof t === "undefined" || t-- > 0) {
        setTimeout(interv, w);
        try {
            func.call(null);
        }
        catch(e) {
            t = 0;
          throw e.toString();
        }
      }
        };
    }(wait, times);

  setTimeout(interv, wait);
}


function get_current_utc_time() {
  var curr_date_obj = new Date();
    var time_utc = "";

    // somehow the date format is not accurate.
  //var time_utc = dateFormat(now, "yyyy-mm-dd h:MM:ss", true);

    var year = curr_date_obj.getUTCFullYear(); 
    var month = add_zero(curr_date_obj.getUTCMonth() + 1); // count from 0
    var date = add_zero(curr_date_obj.getUTCDate()); // count from 1
    var hr = add_zero(curr_date_obj.getUTCHours());
    var min = add_zero(curr_date_obj.getUTCMinutes()); 
    // we ignore the second
    var sec = "00";

    time_utc = year + "-" + month + "-" + date + " " + hr + ":" + min + ":" + sec;

    console.log("-current utc-");
    console.log(time_utc);

  return time_utc;
};


// http://www.w3schools.com/jsref/jsref_getutchours.asp
function add_zero(i) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
}


function insert_into_pending_cmd(msg_obj) {
  console.log();
  console.log("-insert_into_pending_cmd-");

    var schedule_id = msg_obj.schedule_id;
    var device_name = msg_obj.device_name;
    var cmd = msg_obj.cmd;
    var is_pending = msg_obj.is_pending;

  if(is_pending) {
    return Promise.resolve();
  }
  else {
    var curr_time = get_current_utc_time();
    var sql = "insert into Command set CommandDate = " + "'" + curr_time + "'" + "," + "RemoteName = " + "'" + device_name + "'" + "," + "CommandJSON = " + "'" + cmd + "'" + "," + "CommandComplete = 0" + "," + "ScheduleId = " + "'" + schedule_id + "'";

    return g_pool.query(sql).then(function(){
      return Promise.resolve();
    });
  }
}


function is_schedule_cmd_already_pending(msg_obj) {
    console.log();
  console.log("-is_schedule_cmd_already_pending-");

    var schedule_id = msg_obj.schedule_id;
    var device_name = msg_obj.device_name;
    var cmd = msg_obj.cmd;
    var is_run = msg_obj.is_run;

    var local_msg_obj = {};

  if(is_run) {
    var sql = "select count(*) as num from Command where ScheduleId = " + "'" + schedule_id + "'" + " and CommandComplete = 0 and (UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(CommandDate)) < 600 and (UNIX_TIMESTAMP(UTC_TIMESTAMP()) - UNIX_TIMESTAMP(CommandDate)) > 0";
    return g_pool.query(sql).then(function(rows){
      var num = rows[0].num;
      if(num == 0) {
                local_msg_obj = {
                    schedule_id: schedule_id,
                    device_name: device_name,
                    cmd: cmd,
                    is_pending: false
                };
        return Promise.resolve(local_msg_obj);
      }
      else {
                local_msg_obj = {
          schedule_id: schedule_id,
          device_name: device_name,
          cmd: cmd,
          is_pending: true 
        };
        return Promise.resolve(local_msg_obj);
      }
    });
  }
  else {
        local_msg_obj = {
        schedule_id: schedule_id,
      device_name: device_name,
      cmd: cmd,
      is_pending: true 
    };
    return Promise.resolve(local_msg_obj);
  }
}




function is_matchup_schedule_time(row) {
    // get all field
  var schedule_id = row.ScheduleId;
  var device_name = row.ScheduleRemoteName;
  var day_code = row.ScheduleDaycode;
  var schedule_time = row.ScheduleTime;
  var cmd = row.ScheduleCommandJSON;

  // get hour and min
  var schedule_time_arr = schedule_time.split(":");
  var schedule_hour = schedule_time_arr[0];
  var schedule_min = schedule_time_arr[1];

  // print
  console.log();
  console.log();
  console.log("- schedule_id, device_name, day_code, schedule_time, schedule_hr, schedule_min, cmd -");
  console.log(schedule_id);
  console.log(device_name);
  console.log(day_code);
  console.log(schedule_time);
  console.log(schedule_hour);
  console.log(schedule_min);
  console.log(cmd);

  // curr date obj
  var curr_date_obj = new Date();
  var curr_date_code = add_zero(curr_date_obj.getUTCDay());

    // print current
  console.log();
  console.log("- curr_date_code, curr_h, curr_min - ");
  console.log(curr_date_code);
  console.log(add_zero(curr_date_obj.getUTCHours()));
  console.log(add_zero(curr_date_obj.getUTCMinutes()));

    // var
    var msg_obj = {};

    // Match up day
  if(day_code == curr_date_code) {
    console.log();
    console.log(".. match up day ..");

    // Match up hour
    var curr_hour = add_zero(curr_date_obj.getUTCHours());
    if(schedule_hour == curr_hour) {
      console.log();
      console.log("~~ match up hour ~~");

      // Match up min
      var curr_min = add_zero(curr_date_obj.getUTCMinutes());
      if(schedule_min == curr_min) {
        console.log();
        console.log("## match up d-h-m, run ##");

                msg_obj = {
                    schedule_id: schedule_id,
                    device_name: device_name,
                    cmd: cmd,
                    is_run: true                                    
                };

                return Promise.resolve(msg_obj);            
      }
    }
  }
  else {

  }

    //
    msg_obj = {
    schedule_id: schedule_id,
    device_name: device_name,
    cmd: cmd,
    is_run: false 
  };

    return Promise.resolve(msg_obj);
}


// NOTE -------------
function process_schedule_rows(rows) {
    return Promise.mapSeries(rows, function(row) {
        return is_matchup_schedule_time(row)
            .then(is_schedule_cmd_already_pending)
            .then(insert_into_pending_cmd)
            .catch(function(e){
                throw e;
            })
    });
}


function do_schedule() {
  console.log();
  console.log("---- start do_schedule ----");

  g_pool.query("select * from Schedule order by ScheduleId asc")
  .then(process_schedule_rows)
    .catch(function(e){
        throw e;
    });
}


// main func
function main() {
    console.log("db host:");
  console.log(config.db_host);

    connect_db();

    interval(function(){
        do_schedule();
    }, 5000, undefined);

    // Clean up
  ON_DEATH(function(signal, err) {
    console.log();
    console.log("-- script interupted --");
    console.log("close db");

    // close db
    close_db();    

    process.exit();
  });

}


// run main func
main();

update 1

我已将代码更新为递归,但插入仍然发生两次。

function do_schedule() {
  console.log();
  console.log("---- start do_schedule ----");

  g_pool.query("select * from Schedule order by ScheduleId asc")
  .then(process_schedule_rows)
  .delay(2000)
  .then(do_schedule)
  .catch(function(e){
    throw e;
  });
}

update 2

当前,该脚本正在检查命令是否已插入数据库,如果是,则转到下一个任务。如果不是,它将命令插入到挂起表中。

该脚本每2秒检查一次,对于mysql检查是否已经有命令来说可能太快了。

嗯,我把它设置为2分钟,同样的问题仍然出现。 i.g 插入两次。

function do_schedule() {
  console.log();
  console.log("---- start do_schedule ----");

  g_pool.query("select * from Schedule order by ScheduleId asc")
  .then(process_schedule_rows)
  .delay(120000) <------------
  .then(do_schedule)
  .catch(function(e){
    throw e;
  });
} 

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单的 schdule Nodejs 脚本在连接到远程数据库时插入记录两次 的相关文章

随机推荐

  • 在数据注释的ErrorMessage属性中使用html

    任何人都知道是否可以执行以下操作 public class User public Guid UserID get set Required ErrorMessage A school selection is required Range
  • HTTP 状态代码 411 - 需要长度

    我尝试从服务器获取数据 我使用 NSURLConnectionDelegate NSURLConnectionDataDelegate 有代码 目标 C void sendRequest NSURL url NSURL alloc init
  • 如何获得 Mac 操作系统上的峰值内存?

    在 Windows 中 我可以通过调用 GetProcessMemoryInfo 获取峰值内存使用情况 function TProcess Peek Cardinal var PMC PPROCESS MEMORY COUNTERS PMC
  • 如何转义 NSString 以在 NSURL 中使用? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 到目前为止我的发送按钮得到了这个代码
  • 何时使用 ko.utils.unwrapObservable?

    我使用 KnockoutJS 编写了一些自定义绑定 我仍然不确定何时使用ko utils unwrapObservable item 查看代码 该调用基本上检查是否item是一个可观察的 如果是 则返回value 如果不是 则返回value
  • 如何从asp.net中的复选框列表控件返回选定的项目

    我试图以字符串形式返回动态绑定的复选框列表控件中选定的项目 但没有成功 我希望有人能提供帮助 在我的代码隐藏文件中 我连接到一个名为 users 的类并构建一个数据表 然后我将数据表绑定到 cblist 控件 private void po
  • Bootstrap 模式:背景在切换时跳到顶部

    我有一个模态问题 我在页面上有一个按钮 可以切换模式 当模式出现时 页面跳转到顶部 我已尽一切努力寻找解决方案 等等 但我真的迷失了 EDIT 我也尝试过 myModal modal show 但它具有完全相同的效果 当模态打开时modal
  • 没有找到处理意图的活动?

    我正在编写一个程序 当特定的短信到达手机时 应调用应用程序中的主要活动 我已经注册了一个BroadcastReceiver调用该活动的意图是onReceive 方法 问题是 每次我发送这条特定的短信时 我都会收到强制关闭消息 阅读 logc
  • C# - 我应该使用什么,接口、抽象类还是两者?

    因此 假设我正在用 C 构建某种房地产应用程序 对于每种类型的财产 我将创建一个类 例如 ResidentialProperty 和 CommercialProperty 这两个类以及所有其他属性类将共享一些公共属性 例如 Id 标题 描述
  • import jwt 导入错误:没有名为 jwt 的模块

    我一直在尝试运行这个项目https github com udacity FSND Deploy Flask App to Kubernetes Using EKS https github com udacity FSND Deploy
  • 在 C++ 中获取所有打开的窗口的列表并存储它们

    我目前正在尝试获取所有打开的窗口的列表并将它们存储在向量中 我一直在查看代码 以至于解决方案可能非常简单 但如果没有全局变量 我想避免 我似乎无法完成它 这是代码 include stdafx h include json h includ
  • 按月和日分组的事件直方图

    我正在尝试根据多年但按月和日分组的一组数据制作每个事件发生次数的直方图 或其他图 基本上 我想要从 3 月 1 日开始的一年长的 x 轴 显示每个日期出现的次数 并根据分类值对这些日期进行着色 以下是数据集中前 20 名的条目 goose
  • ValueError:参数 scipy rv_continuous 中的域错误

    我试图使用 scipy stats rv continuous 对给定概率密度函数 pdf 的随机变量进行采样 class Distribution stats rv continuous def pdf self x a c return
  • 在 Stata 的 do-file 中将命令分成几行

    我想运行keepStata 12 中 do 文件中的命令 keep a1 a2 a3 a4 a5 b1 b2 b3 b4 b5 c1 c2 c3 c4 我想要的是执行以下操作 keep a1 a2 a3 a4 a5 b1 b2 b3 b4
  • C++ 和 OpenCV:白色像素聚类算法

    我有一个二值图像 黑色和白色像素 我想根据彼此之间的距离将白色像素聚类成组 对象 并检索每个聚类的质心 这是我必须处理的示例图像 框架为紫色 我想检查聚类方法是否可以提供我正在寻找的结果 这意味着我试图避免在知道它值得之前自己实现算法 Op
  • 带有我的应用程序图标的安全中心符号盾

    我开发了一个需要管理员权限才能执行的应用程序 在 Windows 7 上运行应用程序 用户始终必须以 以管理员身份运行 启动应用程序 否则我的应用程序会提示用户 您没有管理权限等 这是可以理解的 因为 Windows 7 中有 UAC 要摆
  • 设置模拟位置时 GPS 提供商未知错误?

    我正在尝试设置我的模拟位置 但是 我收到以下错误 提供商 gps 未知 并且不确定出了什么问题 我已经获得了在manifest xml 中声明的所有权限以及所有参数 模拟定位法 Initiates the method to set the
  • 翻转 OpenGL 纹理

    当我正常从图像加载纹理时 由于 OpenGL 的坐标系统 它们是颠倒的 翻转它们的最佳方法是什么 glScalef 1 0f 1 0f 1 0f 反向映射纹理的 y 坐标 手动垂直翻转图像文件 在 Photoshop 中 加载后以编程方式翻
  • 检查元素在溢出滚动 DIV 中是否完全可见[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我已经为元
  • 简单的 schdule Nodejs 脚本在连接到远程数据库时插入记录两次

    我有一个时间表nodejs脚本 基本上 它有时间表和命令表 调度表有很多命令行 Nodejs 脚本每 5 秒检查一次调度表 如果预定时间与当前时间匹配 我将命令行 从计划表 插入到命令表中 错误是 我在笔记本电脑上运行脚本并进行测试数据库的