Redmine + view customize pluginで連続タスク入力を楽に
Futureパターン2
concurrent-rubyをつかうとfutureパターンが、かなりきれいに書ける。
require 'concurrent-edge'
Concurrent.future {
raise "exception" if [true, false].sample
true
}.then {|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}.rescue{|m|
puts "failed #{m}" # 失敗した時の処理
}.then{|m|
puts "finished" # finalize
}
sleep 0.1
SlimでHTMLメールを送る
HTMLメールをrubyで送るのにslimテンプレートエンジンを使いたくて。
require 'mail'
require 'slim'
mail = Mail.new do
from = 'foo@example.net'
to = 'bar@example.net'
subject = 'html mail'
end
@name1 = 'Sherlock Holmes'
@name2 = 'John Watson'
mail.html_part = Slim::Template.new('template.slim').render(self)
puts mail.to_s
template.slim
p =@name1 + ' is a private detective'
p =@name2 + ' is his assistant'
Futureパターン
EventMachineでFuture(Promise)パターンするときの例文をメモ
GitHub - cotag/em-promise: A promise/deferred implementation for EventMachine
require 'em-promise'
def testMethod
deferred = EM::Q.defer
EM.defer do
begin
# databaseなどを非同期処理
raise "exception" if [true, false].sample # テストなのでわざと例外発生
deferred.resolve('true') # 成功した時はresolveを実行、引数を渡せる
rescue => e
deferred.reject(e) # 例外のときはrejectを実行、引数を渡せる
end
end
deferred.promise # promiseを返す
end
EventMachine.run do
testMethod.then(proc{|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}, proc{|m|
puts "failed #{m}" # 失敗した時の処理
}).then(proc{|m|
puts "finished" # finalize
EM.stop
})
puts "async"
end
非同期実行なのでasyncが表示されてからtestMethodが、実行されます。 testMethodの中身を、もうすこしすっきり書きたいので、書き直し。
require 'em-promise'
def future
deferred = EM::Q.defer
EM.defer do
yield(deferred)
end
deferred.promise
end
def testMethod
future do |dfr|
begin
# databaseなどを非同期処理
raise "exception" if [true, false].sample # テストなのでわざと例外発生
dfr.resolve('true') # 成功した時はresolveを実行、引数を渡せる
rescue => e
dfr.reject(e) # 例外のときはrejectを実行
end
end
end
EventMachine.run do
testMethod.then(proc{|m|
puts "succeed #{m}" # 成功した時の処理、viewになげたり
}, proc{|m|
puts "failed #{m}" # 失敗した時の処理
}).then(proc{|m|
puts "finished" # finalize
EM.stop
})
puts "async"
end
Exchange serverでメールを送信
Microsoft Exchange serverをつかってrubyからメールを送る方法。みんなActionMailerつかってるけどRailsつかわないときは山ほどgemを入れられるのがつらいので、mail + ruby-ntlmでやる方法をメモ。
require 'mail'
require 'ntlm/smtp'
Mail.defaults do
delivery_method :smtp, {
:address => 'mail.server.com',
:domain => 'domain name',
:user_name => 'user name',
:password => 'password',
:authentication => :ntlm,
:enable_starttls_auto => true
}
end
Mail.deliver do
from 'your email address'
to 'recipients'
subject 'Hello'
body 'Test'
end
NVD3.js
綺麗なチャートを表示するのにnvd3.jsを使ってるんだけど、ハマリどころが多いのでメモ。
追記> こちらにちゃんとしたdocumentがありました。 Nvd3 - reusable charts for D3.js
- データは各シリーズでx値が一致して抜けがないように。抜けは0やnullで補完する。x値の順序も同じようにソートしておく。
chartのx,yメソッドで値のスケーリングや演算ができるが、おかしくなることも多いので、演算済みのデータを渡すのが吉。
chart.x(function(d) { return d['x'] / 1000 })
日付はUnix tampstampをm secでわたす。javascriptで以下のように希望のフォーマットに変換する。
chart.xAxis.tickFormat( function(d) {return d3.time.format('%Y-%m-%d')(new Date(d));});
色を変えたいときはjavascriptでcolorをインジェクトしたが、元データに埋め込んでも可。
data[0]['color'] = '#00cc00';
グラフのサイズはsvgタグのサイズで指定(slimつかってます)
div#qty svg style="height:300px; width:100%;"
要望: line chartで、ぬけてるポイントは飛ばして線をつなげてほしい。
slimのテンプレを貼っておく
doctype html html head meta charset="utf-8" title NVD3.js template link href="nv.d3.css" rel="stylesheet" script src="d3.min.js" script src="nv.d3.min.js" javascript: d3.json('data.json', function(data) { nv.addGraph(function() { var chart = nv.models.multiBarChart() .rotateLabels(-45) .margin({top: 30, right: 100, bottom: 100, left: 100}); chart.multibar.stacked(true); chart.xAxis .tickFormat(function(d) { return d3.time.format('%Y-%m-%d')(new Date(d));}); chart.yAxis .tickFormat(d3.format(',d')) .axisLabel('Number'); data[0]['color'] = '#00cc00'; data[1]['color'] = '#ffcc00'; data[2]['color'] = '#ff9900'; data[3]['color'] = '#ff3300'; d3.select('#chart svg') .datum(data) .call(chart); nv.utils.windowResize(chart.update); return chart; }); }); body span h2 style="text-align:center;" Test chart div#chart svg style="height:300px; width:100%;"
AccelTCPで遅延削減
ラズパイVPNサーバの総仕上げとしてAccelTCPでレイテンシーを最小化してみた。 AccelTCPは”プロキシサーバ間のコネクションプーリングにより、TCPコネクションの確立時に発生する3Wayハンドシェイクのオーバーヘッドを削減し、比較的小さなデータのやりとりを行う通信の待ち時間を大幅に短縮できます。”というものです。これで日独間のping 300ms分の遅延を減らすのが目的です。
web browser --> acceltcp:8080 --> (SoftEther VPNでL2TP/IPsec) --> acceltcp:10381 --> squid:3128 --> web site というフローになる。
まず、ラズパイにはsquidをhttp proxyとしてインストールしてポート3128で待機しておく。 キャッシュはいらないので/etc/squid/squid.confで
cache_dir null /tmp
としてディスクキャッシュは無効にしておく。 AccelTCPのbuildは簡単です。
sudo apt-get install libev-dev
git clone git://github.com/KLab/AccelTCP.git
cd AccelTCP
cmake .
make
sudo cp acceltcp /usr/local/bin
まずラズパイにAccelTCPサーバを立てる。AccelTCPは10381で待機します。-4でipv4にするか明示的に自アドレスを書かないとaddress already in useと言われました。バグっぽいです。
acceltcp -q -- --server -4 10381:127.0.0.1:3128
または
acceltcp -q -- --server 127.0.0.1:10381:127.0.0.1:3128
クライアントは自分のmacで下のようにして100本ほどプールを作ります。ラズパイのipは192.168.0.100とします。
acceltcp -q -- -4 --connection-num=100 8080:192.168.0.100:10381
あとはwebブラウザのプロキシを127.0.0.1:8080にすると、日本のサイトへのアクセスは爆速になります。ベンチマークだと1.5倍から2倍弱ですが、体感はもっと速い感じです。webのように小さなファイルをたくさんダウンロードすると効果はてきめんです。http/2が広まるまでは役に立ちそうです。 (googleのdata compression proxyもかなり速い)
ここまでくるとSoftEtherは拠点間接続にして常時つないでおき、AccelTCPもつなぎっぱなしにしておいたほうが使い勝手が良さそうですね。プロキシだけ切り替えればwebへの経路が変わるというのがよさそう。