Shogo's Blog

Aug 20, 2018 - 1 minute read - javascript time

〜夏休みの自由研究〜 電波時計のサマータイム対応状況を調べてみた

僕は知っています。 ぜひ、みなさんもお手元の電波時計で試してみてください! と書いても、試してくれる人なんていないことを。 僕は知っています。 説明書や仕様書に書いてあったとしても、書いてあるとおりに動作する機械なんて、ほんの一握りだということを。 というわけで、楽しい夏休みの自由研究です。 秋葉原で適当に買った1000円から3000円くらいの電波時計に、サマータイムのフラグを有効にした電波を受信させてみて、どういう挙動になるか調査してみました。 TL;DR 10機種(SEIKO, CITIZEN, CASIO, MAG, ELECOM, その他)に対して、サマータイムフラグを有効にした状態で Web JJY の電波を送信しました。 今回の調査範囲では、夏時間の時刻(1時間 or 2時間ズレた時刻)を表示する時計は見つからなかった 夏時間実施中(DST)と表示 する時計は実在する 室内で使うならCASIOの電波時計はクオーツ時計だと思ったほうがいい 電波受信の様子をYouTubeにあげておいたので興味のある方はどうぞ。 背景 2018年、日本は記録的な猛暑に見舞われ、 観測史上最高の気温41.1度を記録し、 熱中症とみられる症状で90人以上が亡くなるという甚大な被害を被った。 今週の天気 記録的な猛暑 底知れぬ暑い夏 日本で猛暑 気温41.1度で観測史上最高 気象庁「災害と認識」熱中症死の疑い6日で90人超 この記録的猛暑を受け、政府・与党によって2020年の東京五輪・パラリンピックの酷暑対策として、夏の期間だけ時間を2時間繰り上げる「サマータイム(夏時間)」の導入が検討されている。 酷暑対策でサマータイム導入へ 秋の臨時国会で議員立法 31、32年限定 これに対して、「電波時計が狂うのではないか」「日本中の電波時計がゴミになる」等、電波時計が正しい時刻を示さなくなるとの指摘が相次いでいる。 サマータイム導入で「電波時計が狂う」? メーカーに聞いた サマータイムで日本中の電波時計がゴミになる(かも)という話 電波時計は、NICT(情報通信研究機構)が提供している標準電波(JJY)を受信し、時刻の同期を行っている。 この標準電波には、時、分、通算日、年、曜日といったタイムコード情報に加え、 将来の拡張性のための「予備ビット」が設けられている。 この予備ビットに関して、「標準電波の出し方について」には、夏時間情報として意味を持たせる場合の例が記載されているが、これはあくまでも例であり、告示などで正式に決まっているものではない。 しかし、現実に市販されている電波時計のなかにも、仕様上予備ビットの状態を認識する機種がする。 標準電波の送信周波数40kHzを提供する「おおたかどや山標準電波送信所」は1999年6月運用開始、送信周波数60kHzを提供する「はがね山標準電波送信所」は2001年10月運用開始である。 日本でサマータイムが導入されたのは1948年から1951年の期間だけなので、 今後サマータイムが導入されることとなれば、標準電波の運用が始まってから初のサマータイム導入となる。 夏時刻法 - Wikipedia 長波帯標準電波施設 パンフレット(PDF) そのため、仕様上はサマータイムへ対応している電波時計であっても、初のサマータイム実施によって未知の挙動を示すことが十分に想定される。 そこで、本記事では、実際にサマータイム実施中の電波を電波時計に受信させ、 どのような挙動を示すのかを明らかにする。 目的 2018年8月現在日本で市販されている電波時計が、サマータイムの情報を含んだ標準電波(JJY)を受信した場合の挙動を調査し、 仮に、2019年、2020年にサマータイムが導入された場合の影響を明らかにする。 実験方法 秋葉原で購入した以下の電波時計に対して、標準電波と同様の電波を送信し、時刻の同期を行う。 CITIZEN 8RZ152 CITIZEN 4RL432-019 SEIKO SQ698S SEIKO KR331W MAG T-694 SM-Z ELECOM CLK-DD001RD 京都大和 171038 (製造元不明) 31756 CASIO DQD-710J-8JF CASIO TTM-160NJ-8JF 電波の送信には、Samsung Galaxy Note8 SC-01K を用いて、JJYシミュレータWeb版を実行する。

Aug 19, 2018 - 1 minute read - go golang wasm

GoAst ViewerをWebAssemblyへビルドしてみた

もうすぐリリースのGo1.11ではWebAssemblyのサポートが予定されています。 (2018/08/19現在の最新版はGo1.11rc1) Go言語がWebAssemblyをサポートへ。GOARCHは「wasm」、GOOSは「js」に 正式リリース前に少し遊んでみようということで、@yuroyoroさんのGoAst ViewerをWebAssemblyへビルドしてみました。 GoAst Viewer WebAssembly Version shogo82148/goast-viewer JavaScriptの連携方法 コードをASTに変換し、JSONとしてエンコードする部分(ast.go)に関しては、一切変更しなくても動きました。素晴らしい。 ただし、さすがにブラウザ上でHTTPサーバーは動かない(そういえば試してないけど、動かないよね??)ので、JavaScriptとの連携部分を実装してあげる必要があります。 syscall/jsパッケージはまだ実験段階というステータスで機能が限られているので、 連携には少し工夫が必要です。 JavaScriptからGoの関数を呼ぶ JavaScriptからGoの関数を呼ぶには window にコールバック関数として必要な関数を登録します。 // GoASTParse 関数を定義(Go言語) js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) { source := args[0].String() // ...ASTへの変換処理... })) 戻り値をGoからJavaScriptへ返す js.NewCallback なのですが、もともとは addEventListener にわたすコールバック関数なので、 関数の戻り値を受けわたす方法がありません。 回避方法はいろいろあるでしょうが、今回はコールバック関数の引数にコールバック関数指定してもらうことにしました。 // GoASTParse 関数を定義(Go言語) js.Global().Set("GoASTParse", js.NewCallback(func(args []js.Value) { source := args[0].String() // ...ASTへの変換処理... args[1].Invoke(string(body)) })) // GoASTParseを呼び出す(JavaScript) GoASTParse("package main; func main() {}", function(body) { // ASTの表示処理 }) まとめ Goのバイナリ全般に言えることですが、WASMになってもやっぱりサイズが大きい(3.5M)。 今後のパフォーマンス向上に期待です。 GoよりAngulerJSの方が難しかったʕ ゚皿゚ ʔ

Aug 11, 2018 - 1 minute read - javascript time

Web JJY が夏時間に対応しました

サマータイムなんて日本人には関係ないと思っていた時期が僕にもありました。 ところが何やら日本にもサマータイムがやってくる動きがあるようです。 酷暑対策でサマータイム導入へ 秋の臨時国会で議員立法 31、32年限定 さて、長波JJY(市販の電波時計のための電波)には夏時間の情報が含まれています。 「将来の拡張性のための予備ビット」という扱いなので、対応している時計なんてないだろう、と思っていたら、 なんと対応している時計が存在しているらしいということを知りました。 その事実を確かめるため、Webブラウザを使って電波を出してみたで紹介した JJYシミュレータWeb版に夏時間を有効にするチェックボックスを追加しました。 CITIZEN 8RZ152 の動作例 夏時間への同期、完了しました 😂😂😂 pic.twitter.com/3tMcCYdXpP — Ichinose Shogo (@shogo82148) 2018年8月9日 念の為書いておきますが、今は午前8時です — Ichinose Shogo (@shogo82148) 2018年8月9日 DST(Daylight Saving Time)の表示が出て、夏時間に切り替わったことがわかりますが、なぜか6時間もズレています・・・。 もう、こんな時間だ……そろそろ寝よう…… ???お前24時間表記だっただろ?どうしたんだ??? (今は20時です) pic.twitter.com/8PViLOaj85 — Ichinose Shogo (@shogo82148) 2018年8月10日 悲報 11日を迎えることができず pic.twitter.com/pw0k0Qo8RY — Ichinose Shogo (@shogo82148) 2018年8月10日 もはや数字ではないものが出てきた。 まとめ 夏時間に対応した電波時計の存在は事実でした。 しかし、機種によっては挙動がおかしくなるようです(N=1)。 ぜひ、みなさんもお手元の電波時計で試してみてください! JJYシミュレータWeb版 ※ 利用の結果生じた損害について、一切責任を負いません。 参考 標準電波の出し方について 酷暑対策でサマータイム導入へ 秋の臨時国会で議員立法 31、32年限定 Webブラウザを使って電波を出してみた サマータイムで日本中の電波時計がゴミになる(かも)という話 サマータイム導入で「電波時計が狂う」? メーカーに聞いた 「サマータイム導入はコンピュータシステム的に難あり」は本当か サマータイム実施は不可能である from UEHARA, Tetsutaro 僕もサマータイム実施は不可能だと思います・・・。

Jun 20, 2018 - 1 minute read - go golang

S3からファイルを落とすだけのツールを作った

S3からファイルを落とすだけのツールを作りました。 s3cli-mini 目的 流行りのCD(継続的デリバリー)を実践するために、専用のデプロイツールをダウンロードする目的で作りました。 主なデプロイ先はAWSなので、デプロイ操作には awscli が必要です。 しかしCDに使用しているCircleCIが公式に提供しているコンテナイメージにはawscliがインストールされていません。 もちろん apt-get install awscli であとからインストールすることは可能ですが、そのぶんジョブの実行時間が長くなってしまいます。 また、インストールされる awscli のバージョンが古く、ローカル環境ではうまく動くけど、 CircleCI上では最新の機能が使えず失敗するということがありました。 そこでもう awscli を使うことは諦めて、Goで AWS API を叩いてデプロイするバイナリを作ってしまうことを考えました。 Goであればシングルバイナリでインストール可能で、CI/CD環境とローカルでバージョンが一致せず悩まされることはありません。 また並行処理が得意なので、デプロイの時間短縮も図れます。 しかし、このデプロイ用のバイナリをどこに置くか・・・プロジェクト固有の処理が入っているので外部には公開したくない。 かといってプライベートなS3バケットに置くと、ダウンロードに awscli が必要になってしまう・・・。 awscli を使うのは諦めたはずでは・・・という、いわゆる「鶏が先か、卵が先か」問題に陥ってしまいました。 そこでS3からのダウンロードの処理に特化したミニawscliが欲しくなって作成したのが s3cli-mini です。 使い方 現状v0.0.1でサポートしているのは cp コマンドのみです。 S3バケットからファイルをダウンロードしたり、S3バケットへファイルをアップロードしたり、 別のS3バケットへファイルを転送することができます。 # download from a S3 bucket s3cli-mini cp s3://your-bucket/foobar.zip . # upload to a S3 bucket s3cli-mini cp foobar.zip s3://your-bucket/ # copy the file from a S3 bucket to another S3 bucket.

Jun 9, 2018 - 1 minute read - go golang

GoでHTTPとS3を透過的に扱う

Goの http.Transport には RegisterProtocol というメソッドが生えていて これを使うと、 HTTP以外のプロトコルを透過的に扱うことができます。 代表的なのは http.NewFileTransport で、これを使うと、file://path/to/file.txt みたいなURLでファイルにアクセスすることができます。 (Goオフィシャルの例) この仕組を使って、S3へのアクセスも透過的にできるようにしてみたので、メモ。 新しいプロトコルを作成するのは非常に簡単です。 http.RoundTripperインターフェースを実装し、リクエストに応答するレスポンスを作ってあげればいいだけです。 S3の場合以下のようになります。(エラー時の扱いが雑だけど・・・) package main import ( "net/http" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" ) type s3RoundTripper struct { s3 *s3.S3 } func newS3RoundTripper(session *session.Session) http.RoundTripper { return &s3RoundTripper{ s3: s3.New(session), } } func (rt *s3RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { host := req.Host if host == "" { host = req.URL.Host } path := req.URL.Path ctx := req.Context() out, err := rt.

May 16, 2018 - 2 minute read - go golang

Goの構造体のコピーを防止する方法

去年仕込んだネタが見つかってしまったので、macopy 構造体について一応解説。 https://t.co/mHq6oWY3rj macopyさん構造体だったのか・・・ — serinuntius (@_serinuntius) 2018年5月14日 2021-05-25 追記 今はこの方法では動かないというツイートを見かけました。 これで出てくる "Goの文法を使った構造体のコピーを防ぐ方法" が動かなかった話ですが https://t.co/FpEnspIfmN このへんに書いてありました.重要なことはその型がstructであること,Lock だけでなく Unlockも実装されていることでした.https://t.co/zQc6T058Ip このように変更すると検知されました — おりさの (@orisano) May 25, 2021 どうやら Go 1.11 から判定基準が 「sync.Locker を実装しているか」に変わっていたようです。 (修正コミット: c2eba53, Issue: #26165) というわけで、 macopy 構造体を以下のように変更する必要があります。 type macopy struct{} func (*macopy) Lock() {} func (*macopy) Unlock() {} 追記ここまで 目的 深淵な理由で Go の構造体のコピーを禁止したい場合があると思います。 kuiperbelt のケースでは、sync/atomic パッケージを使ってフィールドを更新しているので、 フィールドへの読み書きは必ず sync/atomic パッケージを使わなければなりません。 sync/atomic パッケージを使わずに構造体をコピーするとレースコンディションが発生してしまうので、コピーを禁止する必要がありました。 // https://github.com/kuiperbelt/kuiperbelt/blob/e3c1432ed798716c8e88183518f9126951c227f3/stats.go#L20-L28 type Stats struct { connections int64 totalConnections int64 totalMessages int64 connectErrors int64 messageErrors int64 closingConnections int64 noCopy macopy } // atomic.

Apr 10, 2018 - 2 minute read - hugo go golang

OctopressからHugoに乗り換えた

OctopressからHugoに乗り換えました。 以下のような理由からです。 Rubyの環境をメンテナンスし続けるのが面倒 最近Octopress自体の更新が滞っている ビルド時間が長い 一番最初の理由が大きくて、いつもビルドしていた環境を壊してしまって修復が面倒になってしまいました。 そこでようやく重い腰を上げて移行したというわけです。 移行手順 OctopressからHugoへの移行は先人たちがたくさんいるので、それを参考にします。 # 記事のコピー cp octopress-site/source/_posts/* hugo-site/content/post/ # 画像のコピー cp -r octopress-site/source/images/* hugo-site/static/images/ # 記事のタイムスタンプの形式を変える # Hugoでは、"2016-09-25T15:09:57"のような形式のタイムスタンプでないとパースに失敗します find . -type f -exec sed -i "" -e 's/date: \([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\) \([0-9]\{2\}:[0-9]\{2\}\)$/date: \1T\2:00+09:00/g' {} \; パーマネントリンクを維持するために OctopressからHugoへ移行する方法 のRubyスクリプトを利用させていただきました。 dir = 'content/post/' Dir::foreach(dir) do |filename| if filename =~ /\.markdown$/ slug = filename.gsub(/\d{4}-\d{2}-\d{2}-/, '').sub('.markdown', '') puts "#{filename} : #{slug}" lines = [] File::open(dir + filename) do |f| f.each do |line| lines << line end end File::open(dir + filename, 'w') do |f| lines.

Jan 2, 2018 - 1 minute read - mackerel

Mackerel AWS Integration 用の CloudFormation テンプレートを書いた

昨年の年末から Mackerel の本格導入を始めました。 それに当たって AWS Integration 用の CloudFormation テンプレートを書いたので、 他のプロジェクトでも導入が簡単になるよう公開しました。 shogo82148/cf_mackerel 使い方 GitHub Pages でテンプレートを公開しているので、 template-body にテンプレートのURLを指定して、 新しいスタックを作成するだけです。 aws cloudformation create-stack --stack-name "MackerelIntegrationIamUser" \ --template-body https://shogo82148.github.io/cf_mackerel/mackerel.yaml \ --capabilities CAPABILITY_NAMED_IAM 新しい名前付きIAMロールを作成するので CAPABILITY_NAMED_IAM が必要です。 作成がうまくいくとOutputに以下のようなARNが出力されるので、 MackerelのAWS Integrationの設定画面へ入力しましょう。 arn:aws:iam::xxxxxxxxxxxx:role/MackerelAWSIntegrationRole-ap-northeast-1 ロール名について ロール名が意図せずに変わってしまって連携が切れてしまうのを防ぐため、 ロール名は決め打ちです。 MackerelAWSIntegrationRole-ap-northeast-1 ロール名にリージョン名(この場合は ap-northeast-1)が含まれていますが、 作成されたロールはグローバルなリソースなので、他のリージョンでも使用可能です。 わざわざリージョン名含めているのは CloudFormation の警告にしたがったためです。 警告 IAM リソースに名前を付けると、複数のリージョンで同じテンプレートを再利用した場合に、回復不能なエラーが発生する場合があります。 これを防止するために、Fn::Join と AWS::Region を使用して、次の例のように地域固有の名前を作成することをお勧めします RoleName 回復不能なエラー!! コワイので実際に何が起こるかは試してませんが、警告には素直に従っておくことにします。 参考 AWS::IAM::Role - AWS CloudFormation - mackerelのAWSインテグレーション用IAM Userをcloudformationで作る Tomohiro/tf_mackerel 同じことをするTerraformのモジュール

Dec 6, 2017 - 2 minute read - aws-lambda python mecab

MeCabをAWS Lambdaで動かす(2017年版)

AWS Lambda上で鯖(Mackerel)の曖昧性問題を機械学習で解決しようの記事の中で、 Lambda上でMeCabを動かすことについて以下のように触れられています。 日本語を扱う自然言語処理ではMeCabを扱うことが多いですが、Lambda上でMeCabを動かすのは一手間必要なようです。 確かにLambda上でMeCabを動かすのは一手間必要です。 しかし、参照している記事は少し古くて、今はもう少し手軽にできるようになっています。 ブコメでも言及しましたが、改めて記事として残しておこうと思います。 ビルド方法(2017年版) 結論から言うと Norio Kimura さんのコメント 通りにビルドするのが、2017年12月現在一番楽な方法です。 (お返事すっかり忘れていてスイマセン・・・情報提供ありがとうございます) 調べてみると、AWS Lambda では環境変数 LD_LIBRARY_PATH が既に設定されていて /var/task/lib を含んでいました。元記事で ./configure –prefix=$PROJECT_HOME/local ではなく ./configure –prefix=$PROJECT_HOME とすればライブラリとの動的リンクは何もしなくても実現できます。さらにコードが展開されるディレクトリ /var/task を固定値だと決め打ちして PROJECT_HOME を /var/task にして開発すれば MeCab に渡すパラメーターの設定(-d, -r)も不要になります。undocumented な仕様に2つも依存していて気持ち悪いですが、MeCab を呼ぶ側のコードを Lambda 用に変更する必要がなくなります。 コメント中の元記事というのは、こちらの記事のことです。 AWS Lambda で MeCab を動かす export PROJECT_HOME=/var/task # LAMBDA_TASK_ROOT # 1. プロジェクト用にディレクトリを作成 mkdir -p "$PROJECT_HOME" # 2. MeCabのダウンロードとインストール # googlecodeサービス終了に伴い、ダウンロードURLが元記事と変わっていることに注意 cd "$HOME" curl -fsSL "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE" -o mecab.tar.gz cd mecab-0.996 .

Oct 28, 2017 - 2 minute read - go golang

Go言語の浮動小数点数のお話

元ネタ: [JavaScriptの問題] var a = 0.3 - 0.2; var b = 0.2 - 0.1; var c = a==b; cの中身はどれ? — RAO(らお)@けもケP-31 (@RIORAO) 2017年10月24日 正確な実数計算をやらされるJavaScriptくん #擬竜戯画 pic.twitter.com/ipE56C2YbV — RAO(らお)@けもケP-31 (@RIORAO) 2017年10月26日 コンピューターで浮動小数点数を扱ったことのある人なら一度は経験する、 数学上の計算とコンピューター上の計算が合わない計算の一例ですね。 この件に関して、Go言語では正しく(=数学的な結果と同じように)計算できるとの情報が。 おそらくGoはコンパイラがa=0.1とb=0.1に変換していると思われます。 添付した画像のコードだとtrueになりますが、constをvarに変更するとfalseになります。constはコンパイル時に計算されますが、varは実行時に計算されるためです。 pic.twitter.com/LpKZF2kOjH — morikuni (@inukirom) 2017年10月27日 しかしながら、inukiromさんのこの推察、半分はあってますが、半分は間違っていると思います。 なぜGo言語でこのような結果になったのか、検証してみました。 Goの数値定数の型について 以前Go言語でコンパイル時フィボナッチ数列計算で紹介した Better C - Go言語と整数 #golangにもあるように、 Goの定数には「型がない(場合がある)」「任意の精度で計算してくれる」という特徴があります。 このため、普通はどう考えてもオーバーフローしそうなこんな演算も・・・ package main import ( "fmt" ) func main() { var i uint64 = 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 % 1000000007 fmt.Println(i) } play.golang.org/p/FkMVpY2Fa3 型がない定数同士の演算は 162132938 と正しい答えを出してくれます。