ChicagoBoss源码分析

最近在研究ChicagoBoss框架,在网上找到的资料基本上都是github里的readme篇幅,还有就是官方的一些文档。迫于无奈只能去看源码,以下是我读里源码后的理解: 获取ChicagoBoss源码 git clone https://github.com/ChicagoBoss/ChicagoBoss.git cd ChicagoBoss/ make || ./rebar g-d && ./rebar co 首先先查看下README.md和READMEs,里面有一些相关的介绍,数据库配置之类的。 根据README.md,首先创建自己的第一个ChicagoBoss项目 make app PROJECT=mycb cd ../mycb ./init-dev.sh %%% 启动项目 查看src的目录结构如图:

关于这些结构的介绍可以查看官网上的新手文档:

chicagoboss.org/tutorial.pd… github.com/ChicagoBoss… 下面我记录的是关于数据库配置的: boss.config 默认情况下,项目中的存储是由一个叫mock的adapter负责,查看源码才知道,所谓的mock就是进程字典,见源码: boss_db_mock_controller.erl save_record

NewRecord = Record:set(NewAttributes),
    {reply, NewRecord, [{dict:store(Id, NewRecord, Dict), IdCounter1}|OldState]};
复制代码

在boss_db_controller.erl中的save_record,

    {Adapter, _, Conn} = db_for_record(Record, State),
    {reply, Adapter:save_record(Conn, Record), State};
复制代码
这里的Adapter取值为boss_db_adapter_(DatabaseType):
dynymodb,mnesia,mock, mongodb,mysql,pgsql, riak等。
复制代码

下面是boss_db_adapter_mock.erl的保存记录的函数

save_record(_, Record) ->
    SavedRecord = gen_server:call({global, boss_db_mock}, {save_record, Record}),
    {ok, SavedRecord}.
复制代码

通过poolboy找到boss_db_mock_controller.erl,完成存储。 ChicagoBoss的id有两种,一种是自增的,一种是uuid,见源码

{Id, IdCounter1} = case Record:id() of
        id -> case boss_sql_lib:keytype(Record) of
                  uuid   -> {lists:concat([Type, "-", uuid:to_string(uuid:uuid4())]), IdCounter};
                  _      -> {lists:concat([Type, "-", IdCounter]), IdCounter + 1}
              end;
        ExistingId ->
            case boss_sql_lib:keytype(Record) of
                uuid -> {ExistingId, IdCounter};
                _    ->
                  [TypeString, IdNum] = string:tokens(ExistingId, "-"),
                   Max = case list_to_integer(IdNum) of
                           N when N > IdCounter -> N;
                           _ -> IdCounter
                         end,
                   {lists:concat([Type, "-", IdNum]), Max + 1}
            end
    end,
复制代码

boss_db_controller.erl模块有#state{},

-record(state, {
      connection_state,
      connection_delay,
      connection_retry_timer,
      options,
      adapter,
      read_connection,
      write_connection,
      shards    = [],
      model_dict    = dict:new(),
      cache_enable,
      cache_ttl,
      cache_prefix,
      depth        = 0}).
复制代码

其中cache_enable意为是否缓存,cache_ttl为缓存时间, 缓存默认是不开启的,如果开启,但是没有设置缓存数据库的话,默认是mock,即字典进程, EX:设置缓存为redis,boss.config设置如下:

{cache_adapter, redis},
{cache_enable, true},
{db_cache_enable, true},
{cache_servers, [
	{host, "127.0.0.1"},
	{port, 6379},
	{pass, undefined},
	{db, 0},
	{reconnect, true}]},
复制代码

只有同时设置里cache_enable和db_cache_enable为true,其他数据库才会存入缓存,见源码: boss_model_manager_boss_db.erl

DBCacheEnable = boss_env:get_env(db_cache_enable, false) andalso CacheEnable,
复制代码

但是这些缓存的设置只是在查询时有效,也就是说,在查询是在缓存查不到数据,再转到数据库查找,找到之后存入缓存,并设置过期时间。 在redis部分,源码存在bug: boss_cache_adapter_redis.erl

get(Conn, Prefix, Key) ->
    case redo:cmd(Conn,["GET", term_to_key(Prefix, Key)]) of
        Bin ->
            binary_to_term(Bin)
    end.
复制代码

当查找不到时Bin = undefined,此时binary_to_term(undeinfed)会报错, 修改为 :

get(Conn, Prefix, Key) ->
    case redo:cmd(Conn,["GET", term_to_key(Prefix, Key)]) of
        undefined  ->
            undefined;
        Bin ->
            binary_to_term(Bin)
    end.
复制代码

mysql部分的配置如下:

{db_shards, [
      [
          {db_host, "localhost"},
          {db_adapter, mysql},
          {db_port, 3306},
          {db_username, "root"},
          {db_password, ""},
          {db_database, "cb_mysql"},
          {db_shard_id, cb_mysql},
          {db_shard_models, [my_data]}
      ]
  ]},
复制代码

db_shard_models是模块名,需要为这个模块创建数据库my_datas,,没错,是复数形式。db_adapter表示的是哪个数据库适配器调用,这里是boss_db_adapter_mysql,关于controller,view,model等,看完新手引导,就差不多了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值