アプリを終了させるとビーコンのリージョンに入ってもdidEnterRegionが呼ばれない

ionic2でIBeaconクラス(cordova-plugin-ibeacon)を使用している。
アプリがフォアグラウンド、あるいはバックグラウンドにいるときはdidEnterRegionが呼ばれるのだが、終了させるとdidEnterRegionが呼ばれなくなる。
iOSは7.1からアプリを終了させてもモニタリングは継続してくれるはずだから、何かおかしい。


いつものように色々調べると、このアプリ終了後の挙動は、ビーコンのリージョンに入ったときに裏でアプリが起動され、そこでアプリのコードが実行される仕組みになっているということがわかった。
翻って自分のコードを見ると、アプリを起動して1画面遷移したところでdidEnterRegionをsubscribeしている。
これでは裏でアプリが起動されたときにsubscribeが行われない。


というわけで、最初の画面でdidEnterRegionをsubscribeするようにしたところ、アプリ終了後もdidEnterRegionが呼ばれるようになった。

VMイメージをコピーして使おうとしたらネットワークがこける

VMware Workstation 12 Playerで作成したVM(CentOS7)をマシンAからマシンBに移行しようとしたときのこと。


マシンBにVMware Workstation 12 Playerをインストールして、VMのイメージをvmxが入っているフォルダごとコピーすれば動くと思っていたのだけれど、実行してみるとネットワークがこけてしまう。
色々検索してみると、MACアドレスが変わってしまったのがまずいらしい。
解決策としては /etc/udev/rules.d/70-persistent-net.rules と /etc/sysconfig/network-scripts/ifcfg-* のMACアドレス修正が示されていたが、私の場合はそもそもこの両設定ファイルにはMACアドレスなどなかった。
前者のファイルに至っては設定は全部コメントアウトされていて実質空。
もちろん追加でMACアドレスを書き込んでみてもうまくいかない。
いったいどこでMACアドレスの設定がなされているのかわからず、調べてもさっぱり。


困り果ててうだうだ色々やっていると、VMwareのサイトにこんな記述が。

注:コピーしました オプションを選択すると、新しい UUID と MAC アドレスが生成されます。これにより、ネットワーク内での競合が発生しないことが保証されます。

そういえばVM起動時に「移動しました/コピーしました」の選択肢が出てきて、「コピーしました」の方を押した。
けど…これ、「移動しました」にしておけば良かったんじゃないだろうか。


というわけでVMをもう一度コピーし、「移動しました」を押したところ…何の問題もなくあっさりとネットワークが使えるようになった。

dockerでPostgreSQLのログをDataVolumeに吐きたい

postgresql.confでログを/var/log/pgsqlに吐くように設定する。
そして -v /var/log/pgsql:/var/log/pgsql でホストのディレクトリをマウントさせると、ログ出力でPermission deniedと言われてコンテナがこける。


調べてみるとマウントしたディレクトリはゲスト側では UID=1000, GID=1000 になり、UIDが1000のユーザかrootしか書き込めなくなるとのことだったが、今回の場合は所有者が root:root になっており、どうも話が違う。
色々悩んだ末に、ホスト側の所有者を root ではなく適当な一般ユーザーにしすると、ゲスト側で UID=1000, GID=1000 になることがわかった。


あとはpostgresのUID/GIDを1000にするようDockerfileに書いておけば、ログをDataVolumeに吐くことができる。
1つ注意が必要なのは、yumとかでPostgreSQLをインストールする前にユーザーとグループを作っておかなければならないこと。
インストール後に変更すると、usermod/groupmodでは既存のpostgres所有のファイルまではUID/GIDが変更されないため、また別のところでPermission deniedと言われてしまう。

AOTで画像のインポートをするとCannot find moduleと言われる

Cannot find module '../assets/images/icon.gif'.

だそうだ。
怒られているコードはこんな感じ。

import {Component} from '@angular/core'
import * as icon from '../assets/images/icon.gif'

requireに変えるとコンパイラの怒りが鎮まる。

import {Component} from '@angular/core'
const icon = require('../assets/images/icon.gif')


んーでも前AOTでrequire使ってたら怒られてた気がするんだけどなあ…。
コンポーネント定義中で使うのはだめだけど、それさえ静的に解決できてれば他では使っていいってことかな。

'Response' is not assignable to type 'Response'

Responseを参照する自作ライブラリを使用しようとしたら謎のエラーが。
調べてみたらこんな感じになってた。

my-application
└node_modules
  ├@angular
  └my-library
    └node_modules
      └@angular

my-library中のmode_modulesを削除したら解決。


my-libraryのpackage.jsonのdependenciesと、my-applicationのpackage.jsonのdependenciesに設定されている、共通する依存ライブラリのバージョンが違うとこうなるっぽい?


アプリケーション側でもdependenciesに書くライブラリの場合は依存関係はdevDependencies(とpeerDependencies)に書き、dependenciesには書かないのが良いっぽい?

Can't resolve all parameters for XXX

Angular2.1.1

src/app/services/XXX.service.ts

import {Injectable} from '@angular/core'
import {YYY} from './'

@Injectable()
export class XXX {
  constructor(private yyy: YYY) {}
}

src/app/services/YYY.service.ts

import {Injectable} from '@angular/core'

@Injectable()
export class YYY {
  constructor() {}
}

src/app/services/index.ts

export * from './XXX.service'
export * from './YYY.service'

こーすると↑こんな風に↓怒られるみたい。
循環参照の問題、らしい。

Can't resolve all parameters for XXX

こーやって↓index.tsを経由せずにインポートすると解決するみたい。

src/app/services/XXX.service.ts

import {Injectable} from '@angular/core'
import {YYY} from './YYY.service'

@Injectable()
export class XXX {
  constructor(private yyy: YYY) {}
}

embedded PostgreSQL databaseが起動しなくてClouderaManagerがこける

ある日ClouderaManagerに入れなくなった。
/var/log/cloudera-scm-server以下のログを見るとDBに繋がっていないっぽい。
/var/log/cloudera-scm-server/db.log はこんな感じ。

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=7432001, size=8356855808, 03600).
HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.  You can either reduce the request size or reconfigure the kernel with larger SHMMAX.  To reduce the request size (currently 8356855808 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
        If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.
        The PostgreSQL documentation contains more information about shared memory configuration.


共有メモリ(SHMMAX)が足りない、とのこと。
以前は起動できていたから、それ以降の変更が問題なのだろう。
SHMMAXやらpostgresql.confやらは変更した覚えなし。
やったことといえばvmwareをインストールしたことくらい。


色々探してみると/etc/init.d/vmwareにこんな箇所が。

shmmaxPath=/proc/sys/kernel/shmmax
shmmaxMinValue=268435456 # 256MB

〜略〜

      shmmax=`cat $shmmaxPath`

〜略〜

      if  ((  $shmmax < 1 )) || (( $shmmaxMinValue < 1 )) \
       || (( $shmmax < $shmmaxMinValue )) ; then
         echo "$shmmaxMinValue" > "$shmmaxPath"
         echo ""
         echo "Setting the max shared memory the system will allow to $shmmaxMinValue."
         echo ""
      fi


SHMMAXを書き換えている。
こいつが犯人だろう。
だが変だ。
書き換えの条件は「$shmmax < 256MB」の場合だ。
今これが真なら、8GB必要なClouderaManagerは以前から起動できなかったはずだ。


そこで$shmmaxを調べたところ、18446744073692774399が設定されていた。
でかい。
数値として比較するときにオーバーフローしているのかな?
/etc/sysctl.confにSHMMAXを搭載メモリと同じサイズで設定して再起動。
これでめでたく解決〜と思ったがそうではなかった。


ClouderaManagerは起動するようになったが、ServiceMonitorとHostMonitorにつながらないらしい。
とりあえずClouderaManagerから両者を手動で起動してみる。
どうやら正常に起動できたようだ。
それではエラーの出ているCloudera Management Serviceとクラスタを手動で再起動してみる。
できた。問題ないようだ。


めでたしめでたし。