git fetchで、unable to update local refとエラーが出た場合の対処法
リモートでブランチが削除されたのか、git fetchしようとした時にエラーが出た。 git remote prune origin / git fetch originで解決。
error: there are still refs under 'refs/remotes/origin/XXX` ! [new branch] XXX -> origin/XXX (unable to update local ref)
$ git remote prune origin ... $ git fetch origin From github.com:xxx/xxx * [new branch] XXX -> origin/XXX
distilleryを利用したリリースビルドから、command経由でmoduleを実行する際のハマりどころ
2点ハマりどころがあったのでまとめておく。
リリースビルドに含まれないmoduleを実行していないか
/path/to/bin$ ./some command Elixir.Some.Module run ...
{"init terminating in do_boot",{undef,[{'Elixir.Some.Module',application,[],[]},...,{line,24}]},{init,start_em,1,[]},{init,do_boot,3,[]}]}} init terminating in do_boot ()
/path/to/lib/some
配下で、 Elixir.Some.Module.beam
ファイルが生成されているかどうか確認する。
ETSの上限に達していないか
/path/to/bin$ ./some command Elixir.Some.Module run ...
{"init terminating in do_boot",{{badmatch,{error,{some,{{shutdown,{failed_to_start_child,'XXXX',{shutdown,{failed_to_start_child,'XXXX',{system_limit,[{ets,new,['XXXXXX',[set,public,named_table,{read_concurrency,true}]],[]},...{init,start_em,1,[]},{init,do_boot,3,[]}]}} init terminating in do_boot ()
ETSの上限に達している場合、上記のようなエラーが出る。ETSの上限は ERL_OPTS
から "+e 16384"
のように渡すことが出来る。
distilleryのビルドの設定で、 erl_opts
から設定を追加する。
Exqのenqueueのプロセスを追ってみた
仕事に必要だったのでメモ書き程度に残しておく。
Exq というRedisを利用したJob queueライブラリのコードリーディング。
- Exq.enqueue/4 :
use Exq.Enqueuer.EnqueueApi
とあるので、その中に実体がある。
# Exq.Enqueuer.EnqueueApi def enqueue(pid, queue, worker, args), do: enqueue(pid, queue, worker, args, @default_options) def enqueue(pid, queue, worker, args, options) do GenServer.call(pid, {:enqueue, queue, worker, args, options}, Config.get(:genserver_timeout)) end
GenServer
の仕組みで :enqueue
をメッセージとして送信する。 handle_call
で :enqueue
を処理しているメソッドを探す。
# Exq.Manager.Server def handle_call({:enqueue, queue, worker, args, options}, from, state) do Enqueuer.enqueue(state.enqueuer, from, queue, worker, args, options) {:noreply, state, 10} end
- Exq.Enqueuer.enqueue:
use Exq.Enqueuer.EnqueueApi
とあるので、その中に実体がある。
# Exq.Enqueuer.EnqueueApi.enqueue def enqueue(pid, from, queue, worker, args, options) do GenServer.cast(pid, {:enqueue, from, queue, worker, args, options}) end
handle_cast
で :enqueue
を処理しているメソッドを探す。
# Exq.Enqueuer.Server def handle_cast({:enqueue, from, queue, worker, args, options}, state) do response = JobQueue.enqueue(state.redis, state.namespace, queue, worker, args, options) GenServer.reply(from, response) {:noreply, state} end
# Exq.Redis.JobQueue def enqueue(redis, namespace, queue, worker, args, options) do {jid, job_serialized} = to_job_serialized(queue, worker, args, options) case enqueue(redis, namespace, queue, job_serialized) do \:ok -> {:ok, jid} other -> other end end def enqueue(redis, namespace, queue, job_serialized) do try do response = Connection.qp(redis, [ ["SADD", full_key(namespace, "queues"), queue], ["LPUSH", queue_key(namespace, queue), job_serialized]]) case response do {:ok, [%Redix.Error{}, %Redix.Error{}]} = error -> error {:ok, [%Redix.Error{}, _]} = error -> error {:ok, [_, %Redix.Error{}]} = error -> error {:ok, [_, _]} -> \:ok other -> other end catch :exit, e -> Logger.info("Error enqueueing - #{Kernel.inspect e}") {:error, :timeout} end end def to_job_serialized(queue, worker, args, options) do to_job_serialized(queue, worker, args, options, Time.unix_seconds) end def to_job_serialized(queue, worker, args, options, enqueued_at) do jid = UUID.uuid4 retry = Keyword.get_lazy(options, :max_retries, fn() -> Config.get(:max_retries) end) job = %{queue: queue, retry: retry, class: worker, args: args, jid: jid, enqueued_at: enqueued_at} {jid, Config.serializer.encode!(job)} end
というわけで Exq.Redis.JobQueue.enqueue/4
がほぼ実体であることがわかった。Redisに投げているコマンドの詳細は下記となる。
- sadd: Set型に値を追加する。keyに対応するセットに指定した値を追加。
- lpush: List型に値を追加する。lpushの場合はリストの先頭に追加。
ちなみに dequeue
の処理を追うつもりであったが hexdoc に詳細な解説があったので大体の処理の流れは理解できた。
ロードバイクで仙台まで行ってきた
連休を利用し、3泊4日でロードバイクに乗ってはるばる仙台まで自走してきた。
総走破距離は386kmで、これまでで一番遠くまで行くことが出来た。今回の旅に向けて準備してきたこと、旅の道中、旅から帰宅後の反省も含めて記録しておく。このエントリは1万字を超えているので、どんな旅だったかかいつまんでみたい場合は目次を利用していただきたい。
- 準備編
- 気をつけたこと
- 用意した荷物
- 本編
- 後編
準備編
気をつけたこと
実は去年、同じようにゴールデンウィークを利用して2泊3日でロードバイクに乗って名古屋に行こうとしていた。しかしながら、準備不足で2日目に浜松に到着した時点で体力が底を尽きてしまい、そこから輪行で名古屋に向かったので自走できたのは270kmほどだった。
この経験を踏まえて、今年は下記に気をつけて計画を練った。
1日あたりの走行距離を短縮
去年は1日平均120~130kmの行程で着いたら夕方、しかもヘトヘトで何もする気が起きなかった。自転車旅行で移動がメインの目的ではあるが、日々の目的地に着いた後の観光も(時間は限られてはいるが)楽しみたかったため、1日80km前後を目標に再設定した。
走行中に体に荷物を背負わないようにする
去年リタイアした最大の原因としては、荷物をバックパックに詰めて背負って移動していたため、1日経つ毎に肩の凝りがひどくなったことだった。これを踏まえて、走行時に身につけるものはヒップバッグのみになるようにし、大半の荷物は自転車に積むようにした。
ホテルはコインランドリーがあるところを選ぶ
サイクルウェアは1着しか用意していないので、基本的には宿についたら洗うようにする運用方法を取った。去年は宿に到着後、自分で洗ってたらすごく疲れたので今年はそれを回避。
平地で足を使いすぎない
去年は1日目に静岡の新富士のあたりまで走っていて、行程の終盤に箱根超えがあり、800mほどの登坂をする必要があった。にも関わらず、平地で飛ばしすぎてしまったことで箱根では足が使い物にならずほぼ押して凌いでしまっていた。
県をまたぐ際はほぼ山越えがあると思っていたほうが良いので、それを見据えて平地で気持ちよく走れそうなところもぐっと抑えて足に負担がかからないペースになるように気をつけた。
続きを読むJavascriptで連想配列のDeepCopy
Object.assign を実装当初利用したものの、Safariでは9以上でないと動かないらしい。
jQueryの $.extend
を利用するとオブジェクトのマージという形でDeepCopyが出来る。
var src = fetchSrc(); // 何かしらで取ってくる var dest = {}; $.extend(true, dest, src);
上記の用に記述すると dest
に src
の連想配列がマージされる。 dest
自体はもともと空の連想配列なので、実質 src
のDeepCopyとなる。
第一引数に true
を渡すと再帰的に階層を渡ってマージするので基本的には true
を渡しておいたほうが良さそう。