Hatena::ブログ(Diary)

cooldaemonの備忘録 RSSフィード

2007-07-29

Programming Erlang 発売

Amazon から届くのが楽しみだ!

2007-07-20

無料の SSL 認証局

同僚に教えてもらった。

https://cert.startcom.org/

CA 証明書が予めインストールされているブラウザは下記 URI の通り。

https://cert.startcom.org/?app=140

内輪向けのウェブサービスにぴったりだったので、早速、使わせてもらった。ありがたやぁ。

MacPorts 1.5.0 以降で rsync を使わず svn を使う

OSX 10.7 + MacPort 2.0.1 でも有効でした

社内環境で外部への rsync が使えないので、svn を使って ports tree を更新していたのだが、久しぶりに portindex コマンドを実行したら失敗するようになってた。

そこで、MacPorts を現時点の最新版である 1.5.0 に入れ替えた所、portindex コマンドは動作するようになったが、今度は port コマンドで index ファイルが見つからない旨のエラーが出た。

ports tree を以前は rsync.rsync.darwinports.org_dpupdate_dports と言うディレクトリ配下に入れていたが、今度からデリィレクトリに変更になった様子。

下記に行った作業を残しておく。

新規の場合

cd /opt/local/var/db/dports/sources
sudo svn co http://svn.macports.org/repository/macports/trunk/dports

sudo rm /opt/local/var/macports/sources/rsync.macports.org/release/ports
sudo ln -s /opt/local/var/db/dports/sources/dports /opt/local/var/macports/sources/rsync.macports.org/release/ports

cd dports
sudo portindex

更新の場合

cd /opt/local/var/db/dports/sources/dports
sudo svn update
sudo portindex

参考URI

気紛 - きまぐれ - - Macport using SVN

2007-07-17

supervisor

仕事が落ち着いたので、erlang 勉強再開。

id:cooldaemon:20070625id:cooldaemon:20070630 で作った server を supervisor tree に入れてみた。

-module(sup).
-behaviour(supervisor).

-export([start_link/1, stop/0]).
-export([init/1, worker_spec/2]).

start_link(Code) ->
  supervisor:start_link({local, ?MODULE}, ?MODULE, [Code]).

stop() ->
  case whereis(?MODULE) of
    Pid when pid(Pid) ->
      exit(Pid, shutdown),
      ok;
    _ ->
      not_started
  end.

init(Code) ->
  Flags = {one_for_one, 0, 1},
  Children = [
    worker_spec(counter, []),
    worker_spec(code_lock, [Code])
  ],
  {ok, {Flags, Children}}.

worker_spec(WokerModule, Args) ->
  StartFunc = {WokerModule, start_link, Args},
  {WokerModule, StartFunc, permanent, brutal_kill, worker, [WokerModule]}.

sup:start_link("abcd"). で counter と code_lock が起動し、sup:stop(). で全てが停止する。

proc_lib で echoserver を書き直した

gen_server、supervisor、proc_lib の三つを押さえれば、httpd.erl の起動と停止の動作を理解する事が可能。

って事で、以前 みかログ: Erlang で echo server こちらで添削して頂いた id:cooldaemon:20070614 を proc_lib で書き直してみた。

-module(echoserver3).
-export([start_link/0, stop/0]).
-export([init/1, accept/1, handle_connection/1, recv_loop/1]).

start_link() ->
  proc_lib:start_link(?MODULE, init, [self()]).

stop() ->
  case whereis(?MODULE) of
    Pid when pid(Pid) ->
      exit(Pid, shutdown),
      ok;
    _ ->
      not_started
  end.

init(Parent) ->
  register(?MODULE, self()),

  case gen_tcp:listen(
    8080, [{active, false}, binary, {packet, line}, {reuseaddr, true}]
  ) of
    {ok, ListenSocket} ->
      proc_lib:init_ack(Parent, {ok, self()}),
      accept(ListenSocket);
    {error, Reason} ->
      proc_lib:init_ack(Parent, {error, Reason}),
      error
  end.

accept(ListenSocket) ->
    {ok, Socket} = gen_tcp:accept(ListenSocket),
    spawn_link(?MODULE, handle_connection, [Socket]),
    accept(ListenSocket).

handle_connection(Socket) ->
    gen_tcp:send(Socket, <<"hello\r\n">>),
    recv_loop(Socket).

recv_loop(Socket) ->
    case gen_tcp:recv(Socket, 0) of
        {ok, B} ->
            case B of
                <<"bye\r\n">> ->
                    gen_tcp:send(Socket, <<"cya\r\n">>),
                    gen_tcp:close(Socket);
                Other ->
                    gen_tcp:send(Socket, Other),
                    recv_loop(Socket)
            end;
        {error, closed} ->
            ok
    end.

gen_server 等の behaviour は、proc_lib を元に作られている。よって、特にステータス管理を行わないのであれば、proc_lib で十分。

処理をブロックするなら gen_server を選択できないので proc_lib を使うしかない。

添削・突っ込み 大歓迎。

2007-07-12

Date::Japanese::Holiday を利用して Date::Simple に営業日を加算・減算する method を追加

強引ですが。

package Date::Japanese::BusinessDay;

use strict;
use warnings;

use vars qw($VERSION);
$VERSION = '0.01';

use base qw(Date::Japanese::Holiday);

use Class::Data::Inheritable;

package Date::Simple;

{
    no strict 'refs';
    *{__PACKAGE__ . '::mk_classdata'}
        = \&Class::Data::Inheritable::mk_classdata;
}
__PACKAGE__->mk_classdata(two_day_weekend => 0);

sub increment_business_day {
    my $self = shift;
    my ($day) = @_;

    my $result = $self;
    for (
        my $count = 0,
        my $increment = (0 <= $day ? 1 : -1)
        ;
           (0 <= $day && $count < $day)
        || ($day < 0  && $day < $count)
        ;
    ) {
        $result += $increment;
        next if    $result->is_holiday
                || $result->two_day_weekend == 1
                && $result->day_of_week == 6;
        $count += $increment;
    }
    return $result;
}

sub next_business_day {return shift->add_business_day(1)}
sub prev_business_day {return shift->add_business_day(-1)}

1;

こうやって使います。

use Date::Japanese::BusinessDay;
my $d = Date::Japanese::BusinessDay->new; # or Date::Simple->new;
$d->two_day_weekend(1);
$d->increment_business_day(10);
$d->increment_business_day(-10);

two_day_weekend に 1 を設定すると、土曜日を休日として計算します。