Module: AlWorker::IpcAction

Defined in:
lib/al_worker_ipc.rb

Overview

IPC action モジュール

Aloneコントローラへ、IPCのためのアクションを追加する。 (usage)

class AlController
  include AlWorker::IpcAction

Instance Method Summary collapse

Instance Method Details

#action_ipcObject

Note:

AlWorker::Ipc コールアクション

(GET)

http://*.cgi?ctrl=xxx&action=ipc&ipc=IPCNAME&arg=ARGUMENT_encoded_by_json

(POST)

http://*.cgi?ctrl=xxx&action=ipc
(postdata)  ipc=IPCNAME&arg=ARGUMENT_encoded_by_json


418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/al_worker_ipc.rb', line 418

def action_ipc()
  # http (ajax) リクエスト取得
  case ENV["REQUEST_METHOD"]
  when "GET"
    req = AlForm.prefetch_request_get()
  when "POST"
    req = AlForm.prefetch_request_post()
  else
    return
  end

  # IPC接続
  if @ipc
    # ipcオブジェクトが与えられた。
    # use it.
  elsif @ipc_name
    # ソケット名が与えられた。
    @ipc = AlWorker::Ipc.open( @ipc_name )
  elsif req[:ipc_name]
    # httpリクエストで与えられた。
    @ipc = AlWorker::Ipc.open( req[:ipc_name] )
  else
    # デフォルト値を使用。
    @ipc = AlWorker::Ipc.open()
  end

  # IPC 呼び出し
  json = @ipc.call_json( req[:ipc], req[:arg] )
  puts %Q!["#{@ipc.status_code}", #{json}]!
end

#action_ssevObject

Note:

プロトコル仕様のため、以下の理由で IPC through JavaScript が使えない。

* httpヘッダでパラメータ(ID)を送られる
* Content-Typeが、text/event-streamである(JSONデータではない)

そのため、IPCのパススルー機能(puts/gets)を使ってサーバーと直接chatする。

AlWorker::Ipc コールアクション for Server sent event.



459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
# File 'lib/al_worker_ipc.rb', line 459

def action_ssev()
  # http (ajax) リクエスト取得
  case ENV["REQUEST_METHOD"]
  when "GET"
    req = AlForm.prefetch_request_get()
  when "POST"
    req = AlForm.prefetch_request_post()
  else
    return
  end

  # IPC接続
  if @ipc
    # ipcオブジェクトが与えられた。
    # use it.
  elsif @ipc_name
    # ソケット名が与えられた。
    @ipc = AlWorker::Ipc.open( @ipc_name )
  elsif req[:ipc_name]
    # httpリクエストで与えられた。
    @ipc = AlWorker::Ipc.open( req[:ipc_name] )
  else
    # デフォルト値を使用。
    @ipc = AlWorker::Ipc.open()
  end

  # 先立ってコメントを送ることによって接続を確実にする。
  Alone.add_http_header( "Content-Type: text/event-stream" )
  print ": comment for established connection.\n\n"
  $stdout.flush

  # IPC リクエスト
  id = ENV["HTTP_LAST_EVENT_ID"].to_i
  @ipc.puts "#{req[:ipc]} #{req.merge({LAST_EVENT_ID: id}).to_json}"
  Alone.log "SSEV IPC REQUEST #{req[:ipc]} #{req.merge({LAST_EVENT_ID: id}).to_json}", :debug

  # リプライ
  while txt = @ipc.gets
    print txt
    $stdout.flush  if txt == "\n"
  end


rescue SignalException=>ex
  # This process was killed. (e.g. httpd cgi timeout)
  return if ex.message == "SIGTERM"
  log ex

rescue Errno::EPIPE=>ex
  # The ssev stream was closed.
  # nothing to do.
end