DockerコンテナへのJDKへのインストールが失敗する
1か月前は普通にできていたDockerコンテナ(Ubuntu)へのJDKのインストールが失敗するようになった。
Err:186 http://220.152.35.154:80/data/02c924ae5a628323/archive.ubuntu.com/ubuntu bionic-updates/universe amd64 openjdk-8-jdk amd64 8u181-b13-1ubuntu0.18.04.1 Redirection loop encountered Fetched 94.1 MB in 3min 33s (441 kB/s)
こんな感じのエラーが出て失敗する。
調べてみると、5ちゃんねるにJCOMの回線を使っていて 同様の症状が出ている書き込みを見つけた。 確かにうちのもJCOM回線だ。
どうやらJCOMがキャッシュしているパッケージファイルが破損してしまっているのが原因とのことだったので archive.ubuntu.comからダウンロードするのをやめ、 ftp.iij.ad.jpからダウンロードするようにしたところ上手くいくようになった。
具体的には以下のようなコマンドをたたき、apt install し直す形になる。
sed -i 's|http://archive.ubuntu.com/ubuntu/|http://ftp.iij.ad.jp/pub/linux/ubuntu/archive/|g' /etc/apt/sources.list
こういうの防ぐ方法ないのかなぁ。
RxJSを使い、配列のデータを1件ずつ待ちを挟みながら処理していく。
前回の記事をRxJSを使って書き直したような感じの内容。 前回との違いは元になるデータが配列ってところくらい。
private messages = []; private messageArray = [{message: 'テストメッセージ1'}, {message: 'テストメッセージ2'}] const delayObservable = Rx.Observable.empty().delay(1000); // 1秒待ちを入れるobservableを作っておく let messageObservable = Rx.Observable.from(this.messageArray) .concatMap(msg => { return Rx.Observable.empty().concat(delayObservable).concat(Rx.Observable.of(msg)); // 1秒のディレイを挟みつつ、メッセージをsubscribeのコールバックへ流す }); const initMessageSubscription = messageObservable.subscribe( (msg) => { this.messages.push(msg); // メッセージを順次処理する }, (err) => { console.error(err); }, () => { initMessageSubscription.unsubscribe(); // 終わったらunsubscribeする。 } );
Promiseを使って非同期の処理を直列に処理する方法。
4~5年くらい前にPromiseがイマイチ理解できずにコールバックのネストで済ませてしまった問題をようやく解決できた。。。
Promise.resolve() .then(() => { return new Promise((resolve, reject) => { setTimeout(() => { // 何か処理を書く resolve(); }, 1000); }); }) .then(() => { return new Promise((resolve, reject) => { setTimeout(() => { // 何か処理を書く resolve(); }, 1000); }); }); ````
Clojureで特定の条件になるまで待つ
この例だと10秒待つ感じ。
if の条件を関数とかにして引数でもらうようにすれば大体のパターンに対応できる。
(defn wait-10sec [] (loop [i 0] (if (< i 10) (do (Thread/sleep 1000) (println i) (recur (+ i 1))))))
これはなんかライブラリがありそうな気がするな。
ループの途中でreturn(break)したい
気が付いたら前回のポストからすでに2年弱。早いもんですね。。。。
Pythonでいうところの
objs = [{"a": 1, "text": "test 1 message"}, {"a": 2, "text": "test 2 message"}, {"a": 3, "text": "test 3 message"}] for o in objs: if o["a"] == 3: return o
こんなことをClojureで実現したかったので考えてみたけど こんなのしか浮かばなかった。
user> (def objs [{:a 1 :text "test 1 message"} {:a 2 :text "test 2 message"} {:a 3 :text "test 3 message"}]) #'user/objs user> (loop [o objs] (when-not (empty? o) (if (= 3 (-> o first :a)) ;; ここの3を変える (-> o first) (recur (rest o)))))
pythonで3行なんだし、もうちょっと縮められないかまた考えておこう。
それにしても、よくこんなことも知らずに今までやってこれてきたもんだ。
2018-04-03 追記
id:ayato0211 あやぴーさん曰く、この例程度であれば filter + first でも良いとのこと。
(first (filter #(= 3 (:a %)) objs))
やっぱ、clojure使ってる人はこっちの方がわかりやすかったりするのかな?
あと、reduce/reducedなんてのもあるらしい。
(reduce #(if (= (:a %2) 3) (reduced %2)) nil objs)
あやぴーさん、ありがとうございます。とても勉強になりました。 m(_ _)m
Selmerを使ってみる
Hiccupにどうしても慣れることができなかったので、Djangoにインスパイアされたと言われるSelmerがどんなものか軽く動かしてみることにした。
project.cljの:dependenciesに以下を追加
[selmer "1.0.7"]
resource/templates配下に
- layout.html
- user/login.html
を用意
<!-- resource/templates/layout.html --> <html lang="ja"> <head> <title>title</title> </head> <body> {% block body %}{% endblock %} </body> </html>
<!-- resource/templates/user/login.html --> {% extends "layout.html" %} {% block body %} <form action="/login" method="post"> <div><input type="text" name="email" value="{{email}}"/></div> <div><input type="password" name="password" value="{{password}}"/></div> <div><input type="submit" value="submit"/></div> </form> {% endblock %}
画面表示用の関数でrender-file を使ってテンプレートの呼び出しとコンテキストの設定
; core.clj (ns selmer-example.core (:require ...省略...) (:use [selmer.parser :refer [render-file set-resource-path!]])) ; project.cljの:resource-paths に resourcesが指定されている必要がある (set-resource-path! (clojure.java.io/resource "templates")) (defn login-view [{email :email password :password :as params}] (println params) (render-file "user/login.html" {:email email :password password})) ...省略....
すんなり動いてくれた。これなら十分実用できそうな気がする。
ループを回して配列に値を追加する
Pythonだとこんな感じの処理をClojureで書くとどうなるかパッとでてこなかったのでこれもメモ
>>> b = [] >>> for i in range(0, 10): ... b.append({"v": i}) ... >>> b [{'v': 0}, {'v': 1}, {'v': 2}, {'v': 3}, {'v': 4}, {'v': 5}, {'v': 6}, {'v': 7}, {'v': 8}, {'v': 9}]
(loop [i 0 v []] (if (< i 10) (recur (inc i) (conj v {:v i})) v)) [{:v 0} {:v 1} {:v 2} {:v 3} {:v 4} {:v 5} {:v 6} {:v 7} {:v 8} {:v 9}]
もうちょっといい書き方ある気がする。