• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
 

ということで、適当なセカンダリで重複を探して予め削除する必要が。 aggregateで探す例)

   1  aggregate([
   2    {:$group => {_id: {user_id:"$user_id", date:"$date"},
   3      uniqueIds: {:$addToSet => "$_id"}, count:{:$sum => 1}}},
   4    {:$match => {count: {:$gt => 1}}}],
   5    allowDiskUse: true)

posted by Png genki on Fri 22 May 2015 at 02:28

WiredTigerが非常に素晴らしいのですが、設定ファイルが

  1. /etc/mongod.conf
  2. /var/lib/mongodb/WiredTiger.basecfg
  3. /var/lib/mongodb/WiredTiger.config

のように沢山あって結構ややこしいです。

基本的には 1. はmongodbの初回起動時だけ有効で、3. が次回以降の再起動で反映されるものになります。 さらに、mongodbを動かしたままWiredTigerの設定だけ変更したい場合は、 mongoのコンソールから

   1  db.adminCommand({setParameter:1, wiredTigerEngineRuntimeConfig:"c
   2  ache_size=8G"})

のように修正できるようです。パラメータ名は 2. のファイルの中身が参考になります。 これによって内部的にはWT_CONNECTION::reconfigureが実行される模様。

修正したら、次回来起動した場合に備えて 3. も書き換えておくと良いでしょう。

posted by Png genki on Wed 13 May 2015 at 03:43

たびたび見失ってGoogleで探すのに苦労するので道標的に。

posted by Png genki on Fri 8 May 2015 at 21:46

二人前の分量です。

  • スペルト小麦(farro)80g セミペルラート(半精麦)
  • にんにく一片
  • 鶏もも肉150g (皮、脂肪を除いた重さ)
  • 白ワイン(辛口)100cc
  • オリーブオイル 25g (エクストラバージン)
  • ローリエの葉1枚
  • 固形ブイヨン1/2
  • 厚切りベーコン50g
  • パルミジャーノチーズ 10g
  • バター 10g
  • タイム一振り
  • エシャロット 1本
  • 人参1/3ぐらい
  • 塩コショウ 適量

手順

  1. スペルト小麦を冷たい水に浸して30分放置し、ザルなどで水を切って流水で洗う。鍋に1リットルの水を入れ、スペルト小麦、にんにく、ローリエを入れて沸騰させ、とろ火にして45分ほど煮込む。

  2. 鶏もも肉の皮と脂肪を取り除き、人参とともに1cm角ほどのサイコロ状に切る。エシャロットはみじん切りにする。

  3. 煮込み終わったスペルト小麦をザルなどで水切りし、ボールに移してオリーブオイルを加えて混ぜ、冷ます。
  4. ベーコンを棒状に切り、フライパンで油が出るまで過熱し、鶏肉、人参、エシャロットを加えて4分間ほど中火で過熱する(人参にしっかり火を通す)
  5. 白ワインを加えて沸騰させ、ブイヨン、塩、スペルト小麦を加えて手早くかき混ぜる。
  6. フライパンに蓋をしてとろ火で5〜10分ほど煮詰める。
  7. バター、パルミジャーノチーズを削り入れ、リゾット状になるように混ぜる
  8. タイムを一振り、塩、胡椒で味を整える。
  9. 皿に盛りつけて完成
posted by Png genki on Sun 26 Apr 2015 at 03:02

   1  //	To use those functions below
   2  //	You need to import CommonCrypto.h in your bridging header.
   3  //		#import <CommonCrypto/CommonCrypto.h>
   4  
   5  func
   6  DataCryptedByAES( operation: CCOperation, p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
   7  	var	wKeyLength = 0
   8  	if		key.length < kCCKeySizeAES128	{ assert( false ) }
   9  	else if	key.length < kCCKeySizeAES192	{ wKeyLength = kCCKeySizeAES128 }
  10  	else if	key.length < kCCKeySizeAES256	{ wKeyLength = kCCKeySizeAES192 }
  11  	else									{ wKeyLength = kCCKeySizeAES256 }
  12  
  13  	if iv != nil { assert( iv!.length == kCCBlockSizeAES128 ) }
  14  
  15  	var	wLength = UInt( ( ( p.length + kCCBlockSizeAES128 - 1 ) / kCCBlockSizeAES128 ) * kCCBlockSizeAES128 )
  16  	let	v = NSMutableData( length: Int( wLength ) )!
  17  	let	s: CCCryptorStatus = CCCrypt(
  18  		operation
  19  	,	CCAlgorithm( kCCAlgorithmAES )
  20  	,	options
  21  	,	key.bytes
  22  	,	UInt( wKeyLength )
  23  	,	iv != nil ? iv!.bytes : nil
  24  	,	p.bytes
  25  	,	UInt( p.length )
  26  	,	v.mutableBytes
  27  	,	wLength
  28  	,	&wLength
  29  	)
  30  	v.length = Int( wLength )
  31  	return ( s, v )
  32  }
  33  
  34  func
  35  DataEncryptedByAES( p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
  36  	return DataCryptedByAES( CCOperation( kCCEncrypt ), p, key, options, iv )
  37  }
  38  
  39  func
  40  DataDecryptedByAES( p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
  41  	return DataCryptedByAES( CCOperation( kCCDecrypt ), p, key, options, iv )
  42  }
  43  
  44  func
  45  DataCryptedByBlowfish( operation: CCOperation, p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
  46  	if iv != nil { assert( iv!.length == kCCBlockSizeBlowfish ) }
  47  
  48  	var	wLength = UInt( ( ( p.length + kCCBlockSizeBlowfish - 1 ) / kCCBlockSizeBlowfish ) * kCCBlockSizeBlowfish )
  49  	let	v = NSMutableData( length: Int( wLength ) )!
  50  	let	s: CCCryptorStatus = CCCrypt(
  51  		operation
  52  	,	CCAlgorithm( kCCAlgorithmBlowfish )
  53  	,	options
  54  	,	key.bytes
  55  	,	UInt( key.length )
  56  	,	iv != nil ? iv!.bytes : nil
  57  	,	p.bytes
  58  	,	UInt( p.length )
  59  	,	v.mutableBytes
  60  	,	wLength
  61  	,	&wLength
  62  	)
  63  	v.length = Int( wLength )
  64  	return ( s, v )
  65  }
  66  
  67  func
  68  DataEncryptedByBlowfish( p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
  69  	return DataCryptedByBlowfish( CCOperation( kCCEncrypt ), p, key, options, iv )
  70  }
  71  
  72  func
  73  DataDecryptedByBlowfish( p: NSData, key: NSData, _ options: CCOptions = CCOptions( kCCOptionPKCS7Padding ), _ iv: NSData? = nil ) -> ( CCCryptorStatus, NSData ) {
  74  	return DataCryptedByBlowfish( CCOperation( kCCDecrypt ), p, key, options, iv )
  75  }
  76  
  77  
  78  //USAGE
  79  
  80  func
  81  UTF8Data( p: String ) -> NSData? {
  82  	return p.dataUsingEncoding( NSUTF8StringEncoding )
  83  }
  84  
  85  func
  86  Usage() {
  87  	let	wKey = UTF8Data( "teststring" )!
  88  	let	wIV = UTF8Data( "12345678" )!
  89  	var	( s, data ) = DataEncryptedByBlowfish( UTF8Data( "testmessage" )!, wKey, CCOptions( kCCOptionPKCS7Padding ), wIV )
  90  	assert( Int( s ) == kCCSuccess )
  91  	( s, data ) = DataDecryptedByBlowfish( data, wKey, CCOptions( kCCOptionPKCS7Padding ), wIV )
  92  	assert( Int( s ) == kCCSuccess )
  93  }
  94  

posted by Face Saturn on Thu 26 Mar 2015 at 08:45

キーチェーンアクセス -> 証明書アシスタント -> 証明書を作成

OreOre.tiff

できた証明書を p12 で書き出し。

openssl pkcs12 -in OreOre.p12 -nodes -out OreOre.pem

でパスワードがついていない pem を作成。 この中に証明書も鍵も入っているので、tls.LoadX509KeyPair の引数は両方とも "OreOre.pem" で大丈夫。

posted by Face Saturn on Wed 24 Dec 2014 at 22:14

   1  package main
   2   
   3  import (
   4  	"net"
   5  	"sync"
   6  	"crypto/rand"
   7  	"crypto/tls"
   8  	"log"
   9  	"encoding/json"
  10  )
  11   
  12  
  13  func
  14  main() {
  15  
  16  	cert, err := tls.LoadX509KeyPair( "OreOre.pem", "OreOre.pem" )
  17  	if err != nil { log.Fatalf( "LoadX509KeyPair:%v", err ) }
  18  	config := &tls.Config{
  19  		Certificates: []tls.Certificate{ cert }, 
  20  		ClientAuth: tls.VerifyClientCertIfGiven, 
  21  		ServerName: "example.com",
  22  		Rand:	rand.Reader,
  23  	}
  24  
  25  	connections := map[ net.Conn ] interface{} {}
  26  	mutex := sync.RWMutex{}
  27  
  28  	broadcaster := make( chan interface{} )
  29  	go func() {
  30  		for {
  31  			data, _ := json.Marshal( <- broadcaster )
  32  			mutex.RLock()
  33  			conns := connections
  34  			mutex.RUnlock()
  35  			for conn, _ := range conns { conn.Write( data ) }
  36  		}
  37  	}()
  38  
  39  	listener, _ := tls.Listen( "tcp", ":6666", config )
  40  	defer listener.Close()
  41  	for {
  42  		conn, _ := listener.Accept()
  43  		mutex.Lock()
  44  		connections[ conn ] = ""
  45  		mutex.Unlock()
  46  		go func() {
  47  			decoder := json.NewDecoder( conn )
  48  			for {
  49  				var	w interface{}
  50  				err := decoder.Decode( &w )
  51  				if err != nil { break }
  52  				broadcaster <- w 
  53  			}
  54  			mutex.Lock()
  55  			delete( connections, conn )
  56  			mutex.Unlock()
  57  			conn.Close()
  58  		}()
  59  	}
  60  }

証明書がオレオレなので openssl で検証。

openssl s_client -tls1 -connect localhost:6666

posted by Face Saturn on Wed 24 Dec 2014 at 22:09

   1  package main
   2   
   3  import (
   4  	"net"
   5  	"sync"
   6  	"encoding/json"
   7  )
   8   
   9  func
  10  main() {
  11  
  12  	connections := map[ net.Conn ] interface{} {}
  13  	mutex := sync.RWMutex{}
  14  
  15  	broadcaster := make( chan interface{} )
  16  	go func() {
  17  		for {
  18  			data, _ := json.Marshal( <- broadcaster )
  19  			mutex.RLock()
  20  			conns := connections
  21  			mutex.RUnlock()
  22  			for conn, _ := range conns { conn.Write( data ) }
  23  		}
  24  	}()
  25  
  26  	listener, _ := net.Listen( "tcp", ":6666" )
  27  	defer listener.Close()
  28  	for {
  29  		conn, _ := listener.Accept()
  30  		mutex.Lock()
  31  		connections[ conn ] = ""
  32  		mutex.Unlock()
  33  		go func() {
  34  			decoder := json.NewDecoder( conn )
  35  			for {
  36  				var	w interface{}
  37  				err := decoder.Decode( &w )
  38  				if err != nil { break }
  39  				broadcaster <- w
  40  			}
  41  			mutex.Lock()
  42  			delete( connections, conn )
  43  			mutex.Unlock()
  44  			conn.Close()
  45  		}()
  46  	}
  47  }

posted by Face Saturn on Wed 24 Dec 2014 at 22:07

 RSpecで現在時刻に関連するテストをするときに、Rails4.1からはTimecopを使わなくても ActiveSupport::Testing::TimeHelpers の to_travel というメソッドを使って現在時刻を設定することができます。

 たとえば、下記のように現在時刻を返すメソッドがあるとします。

   1  class Foo
   2    def now
   3      Time.now
   4    end
   5  end

 正しく現在時刻を返しているかのテストは下記のように書けます。

   1  travel_to Time.new(2014, 11, 24, 9, 30, 0) do
   2    foo = Foo.new
   3    expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
   4  end

 travel_toで現在時刻を設定しているので、expectで評価するときに決まった時間を書いて比較できます。

 ですがもしnowメソッドでDateTime.nowを返していると、to_travelでは対応できません。

   1  class Foo
   2    def now
   3      DateTime.now # <- to_travelで設定した時間ではなく現在時刻が返る
   4    end
   5  end

 その場合にはやはりTimecopを使う必要があります。Gemfileには下記のようにgemを追加。

   1  group :test do
   2    gem 'timecop'
   3  end

 テストは下記のように記述します。

   1  Timecop.freeze(Time.new(2014, 11, 24, 9, 30, 0)) do
   2    foo = Foo.new
   3    expect(foo.now).to eq(Time.new(2014, 11, 24, 9, 30, 0))
   4  end

 travel_to が対応しているのは Time.now と Date.today のみのようです。

 travel_to(date_or_time, &block)
 rails4.1からのtravel_toをrspecで使う

posted by Png akanuma on Tue 25 Nov 2014 at 00:00

環境変数によってRailsアプリの動作を切り替えたいことがあって、
nginx + Passenger で動かしているRailsアプリに環境変数を渡す方法を調べました。

nginx の起動スクリプト(/etc/init.d/nginx)に書いても、
/etc/default/nginx に書いてもうまくいかなかったのですが、
nginx の設定ファイルの location ブロックで
passenger_set_cgi_param で設定することで環境変数が設定できます。

   1  passenger_set_cgi_param HOGE fuga;

これでRailsアプリの中で ENV['HOGE'] で "fuga" という値が取得できるように なります。

参考ページ
16.3.5. Phusion Passengerが提供するアプリケーション
8.6.1. passenger_set_cgi_param

posted by Png akanuma on Sat 22 Nov 2014 at 14:13