Inspirer

最新文章

理解 Rust 2018 edition 的两个新关键字 —— impl 和 dyn

Rust 2018 edition 虽然实际发布时间还没到(本文开始写的时间是 18 年七月底),但是有些 2018 edition 的特性已经随着 Rust 的新版本发布放出,这些已经进入 stable 版的特性必然是应当了解并学习的。其中就有两个本文所要讨论的关键字 —— impldyn

最先出现的 impl 是大家已经熟悉的关键字,不过这次这个关键字除了用于表示实现一个 Trait,还有新的意义,即表达一个既存类型(Existential types),我们可以理解为一个实现了一个特征的 具体对象

官方原文介绍:impl Trait https://rust-lang-nursery.github.io/edition-guide/2018/transitioning/traits/impl-trait.html

impl Trait is the new way to specify unnamed but concrete types that implement a specific trait. There are two places you can put it: argument position, and return position.

trait Trait {}

// argument position
fn foo(arg: impl Trait) {
}

// return position
fn foo() -> impl Trait {
}

不过其意义是什么?与我们另一个要介绍的 dyn Trait 又有什么关系?下面我们正式开始。

Rust 实现动态库加载和基于此功能实现的插件管理

最近开发后端 UCenter 服务,考虑到该服务核心逻辑变动相对少,稳定性要求高,单点处理能力要强,且 IO 瓶颈较少(大多缓存),有较多的校验和加解密工作,因此需要使用性能更为强劲的语言,最终考虑使用 Rust(无 GC、内存安全、性能与 C/C++ 差距不明显)以及其最近风头正劲的基于 Actor 模型的 Web 框架:Actix-web。对于框架和语言的介绍我会另起文章,先说说这个用户中心服务。

用户中心服务提供平台下属多个应用的统一授权工作,无论是第三方登录授权(如基于 OAuth 的授权或对外部以 OAuth 支持)、SSO(Single Sign-On)以及解决跨应用用户数据共享、互通等。虽然服务核心逻辑十分稳定,但对于各类子应用接入会有较多的拓展需求,例如不同应用的专用数据表的访问、多协议适配等。对于动态语言或存在虚拟机的语言而言,动态库加载相对简单,但对于 Rust 这种静态和无(或极小)运行时语言,拓展则相对困难。不过 Rust 提供了 FFI(Foreign Function Interface)支持,我们则利用这个实现我们的需求。

博客长草,非常抱歉,从今天起重新开始更新

博客已长草,这一年多以来变化太大,变动太多,精力无比分散。但是过了这么久发现还是写博客文章能让人沉淀下来,静下心来好好总结之前所学。

所以接下来,争取每月一篇以上的更新,且希望各位支持。如果有什么问题希望能得到更完整的文字教程,可以联系我(Email 在 关于 里),我会根据你们的情况准备文章。

之前说要对博客进行改动也废了,不过不代表不会有,现在这个版本有点旧,而且功能也有严重的缺失,之前的评论系统由于多说的悲剧而悲剧,因此这次我打算自己实现了(本来也不复杂,还是太懒)。这次可能带来的东西有点和以前不一样,所以各位保持关注。

对这一年以来给我来信支持的朋友表示感谢!

为什么重启后 /run 下的文件不在了?

摘自 https://serverfault.com/questions/546966/whats-removing-stuff-from-var-run-at-reboots-from-a-fedora-machine

The software should define what directories it needs in /run (which replaced /var/run in Fedora 15) by placing a configuration file in /usr/lib/tmpfiles.d. During the boot process, systemd-tmpfiles populates /run based on that confguration.

其中解释了 /run 是挂载在临时文件的系统里的,即在系统启动后,添加在里面的数据、文件都是写入内存的,因此重启后自然不存在。

懒得去翻的,本文直接给出一个便于快速查阅的方案。

四舍五入不可取!结算金额,如何保证精确?

今天在 SegmentFault 看到了类似问题,查资料回答那个问题后,决定留个笔记。

我们在计算金额时,难免存在保留位数有限,计算结果需要取舍的情况。往往在电商、银行系统中,金额是以整数形式保存,单位为货币最小单位,例如分。但是在结算时额外的参数如折扣、利率、税率等存在着大量的浮点数,计算结果则需要转换为整数。

简单处理一般是四舍五入,但是这样存在很明显的问题,就是 “入” 的概率大于 “舍”,明显的,遇到 1、2、3、4 舍,遇到 5、6、7、8、9 入,粗看这种就可以发现问题。如果想要两边平衡,则 “四舍六入” 才是合理的,但是,5 怎么办?

laravel 学习笔记 —— 查询构造器(下)

来继续填坑(上个月没发,因此这个月至少两篇)。

上一篇 laravel 学习笔记 —— 查询构造器(下) 中我们正在开始分析查询构造器的 where 方法,作为出场率最高的方法,其中相关的玩意儿足以帮助我们去理解整个组件大致的设计思路和实现细节。由于整体分析实在是太过麻烦(我其实就是懒),因此我们在上一篇的末尾提了三个问题,本文也将顺着这三个问题来进行解析,当然其余的思路类似的,就不在赘述,毕竟精力有限。

上一篇提到的问题是:

  • where 方法中多余的参数是干什么的
  • 方法中的代码为什么要拆分(或者封装)的那么细 ?
  • Expression 这个类是干嘛的 ?

我们就从多余的参数是做什么的开始吧。

Laravel Pipeline 组件的实现

Laravel 框架中有一个非常有趣的功能,就是 HTTP 中间件,我们在定义路由的时候,通过中间件对访问进行过滤。来自外部的请求首先经过全局中间件,若通过,则会继续穿过层层路由组所设置的中间件,在到达目的路由,当然,目的路由也可能定义了个中间件,通过后,该路由的处理对象(如控制器),得到的就是一个经过过滤的请求了。

开始

本文当然不是讨论中间件如何使用,而是其实现的基础。Laravel 框架中有一个组件叫做 Illuminate\Pipeline,意味 “管道”,我们看看下面这个代码示例:

<?php
use Illuminate\Pipeline\Pipeline;

$pipe1 = function ($poster, Closure $next) {
    $poster += 1;
    echo "pipe1: $poster\n";
    return $next($poster);
};

$pipe2 = function ($poster, Closure $next) {
    if ($poster > 7) {
        return $poster;
    }

    $poster += 3;
    echo "pipe2: $poster\n";
    return $next($poster);
};

$pipe3 = function ($poster, Closure $next) {
    $result = $next($poster);
    echo "pipe3: $result\n";
    return $result * 2;
};

$pipe4 = function ($poster, Closure $next) {
    $poster += 2;
    echo "pipe4 : $poster\n";
    return $next($poster);
};

$pipes = [$pipe1, $pipe2, $pipe3, $pipe4];

function dispatcher($poster, $pipes)
{
    echo "result: " . (new Pipeline)->send($poster)->through($pipes)->then(function ($poster) {
            echo "received: $poster\n";
            return 3;
        }) . "\n";
}

echo "==> action 1:\n";
dispatcher(5, $pipes);
echo "==> action 2:\n";
dispatcher(7, $pipes);

上述代码执行结果如下:

==> action 1:
pipe1: 6
pipe2: 9
pipe4 : 11
received: 11
pipe3: 3
result: 6
==> action 2:
pipe1: 8
result: 8

让 Laravel 变得更富有可能 —— 基于 swoole 的 Laravel

现在,Laravel 可以有更多可能。

我基于 Swoole 对 Laravel 框架的底层做了些许调整,使得其在能够运行至 Swoole 提供的强大特性下的同时,又能够不改变原有的开发模式(但是思路可能应该有些许调整了哦~)。现在已经有了一个可用的雏形,项目地址:

https://github.com/chongyi/swoole-laravel-framework

事实上已经有人做过此类工作,不过或多或少都有些不足,使得我们无法在一些工作中直接使用,例如对于文件上传和下载的支持不是很好,亦或者完全改动了原有的开发模式,使得旧的代码很难无缝切换。

当然,目前的情况依旧不允许直接使用在现有的项目中,因为还有很多未知 BUG 的存在。不过问题也在不断解决,毕竟本质上提供 HTTP 服务只要遵循 HTTP 协议就很难出现差池。

当前优先保证了 Laravel 5.1 下的可用,实际情况是 5.2 也能够得到支持,不过我会在基本功能稳定后建立 tag 便于各位后期能够快速通过 composer 安装。

欢迎各位 Star!也希望诸多大牛能够提供更多的建议~