Class: Goat::App

Inherits:
Object show all
Includes:
AppHelpers, FlashHelper
Defined in:
lib/goat.rb

Direct Known Subclasses

BasicApp

Constant Summary collapse

@@error_handler =
nil
@@not_found_handler =
nil
@@around_handlers =
[]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FlashHelper

#flash

Methods included from AppHelpers

#halt, #redirect, #session

Constructor Details

#initialize(req, meth = nil) ⇒ App

Returns a new instance of App.



666
667
668
669
670
671
# File 'lib/goat.rb', line 666

def initialize(req, meth=nil)
  @req = req
  @meth = meth
  @response = Rack::Response.new
  @params = IndifferentHash.from_hash(req.params)
end

Class Method Details

.after(&blk) ⇒ Object



550
551
552
# File 'lib/goat.rb', line 550

def after(&blk)
  around_handlers << [:after, blk]
end

.around_handlersObject



544
# File 'lib/goat.rb', line 544

def around_handlers; @@around_handlers; end

.before(&blk) ⇒ Object



546
547
548
# File 'lib/goat.rb', line 546

def before(&blk)
  around_handlers << [:before, blk]
end

.bind(hook, name = nil, for_response = true) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/goat.rb', line 645

def self.bind(hook, name=nil, for_response=true)
  mname = name || String.random

  lambda do |app, *args|
    kls = app.class

    unless kls.instance_methods.include?(mname)
      Goat.logd "defining #{mname} on #{kls}"
      kls.send(:define_method, mname, hook)
      hook = kls.instance_method(mname)
    end

    if for_response
      # sets the body
      app.respond_with_hook(mname, *args)
    else
      app.send(mname, *args)
    end
  end
end

.call(env) ⇒ Object

end class << self



637
638
639
640
# File 'lib/goat.rb', line 637

def self.call(env)
  self.req_handler.app_class = self
  self.req_handler.handle_request(env)
end

.error(&blk) ⇒ Object



623
624
625
# File 'lib/goat.rb', line 623

def error(&blk)
  @@error_handler = blk
end

.error_handlerObject



627
# File 'lib/goat.rb', line 627

def error_handler; @@error_handler; end

.get(path, hook = nil, &proc) ⇒ Object



530
531
532
533
# File 'lib/goat.rb', line 530

def get(path, hook=nil, &proc)
  hook = proc unless proc.nil?
  req_handler.add_mapping(:method => :get, :path => path, :hook => hook)
end

.handle_rpc(app) ⇒ Object



557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/goat.rb', line 557

def handle_rpc(app)
  req = app.request

  cls = req['cls']
  cid = req['id']
  rpc = req['rpc']
  txn = req['rttxn']
  pgid = req['pgid']
  reqargs = JSON.load(req['args'])

  have_handler = false
  resp = nil

  Goat::NotificationCenter.notify(
    'type' => 'txn_start',
    'txn' => txn,
    'pgid' => pgid
  )

  if comp = Goat.rpc_handlers[cls]
    if comp.include?(rpc)
      Dynamic.let(:txn => txn, :txn_pgid => pgid) do
        have_handler = true
        opts = comp[rpc]
        args = []
        if opts[:live]
          if skel = StateSrvClient.fetch_component(cid)
            component = Kernel.fetch_class(cls).from_skel(skel)
            component.deserialize(skel.live_state)

            args << component
          else
            return respond_failed
          end
        end

        args << IndifferentHash.from_hash(reqargs)

        had_error = false
        begin
          resp = app.respond_with_hook("rpc_#{rpc}", *args)
          resp = opts[:is_get] ? resp.to_json : [200, {}, '']
        rescue Exception => e
          had_error = true
          # even though the actual response returned here doesn't matter too much,
          # we want to call the error handler to make sure any app logic for handling
          # errors is called.
          resp = req_handler.resp_for_error(e, app)
        end

        if opts[:live] && !had_error
          component.update
        end

      end
    end
  end

  Goat::NotificationCenter.notify(
    'type' => 'txn_complete',
    'txn' => txn
  )

  have_handler ? resp : [500, {}, {'success' => false}.to_json]
end

.map(opts) ⇒ Object



540
541
542
# File 'lib/goat.rb', line 540

def map(opts)
  req_handler.add_mapping(opts)
end

.not_found(&blk) ⇒ Object



629
630
631
# File 'lib/goat.rb', line 629

def not_found(&blk)
  @@not_found_handler = blk
end

.not_found_handlerObject



633
# File 'lib/goat.rb', line 633

def not_found_handler; @@not_found_handler; end

.post(path, hook = nil, &proc) ⇒ Object



535
536
537
538
# File 'lib/goat.rb', line 535

def post(path, hook=nil, &proc)
  hook = proc unless proc.nil?
  req_handler.add_mapping(:method => :post, :path => path, :hook => hook)
end

.req_handlerObject



526
527
528
# File 'lib/goat.rb', line 526

def req_handler
  @@reqhandler ||= ReqHandler.new
end

.respond_failedObject



555
# File 'lib/goat.rb', line 555

def respond_failed; [500, {}, ['failed']]; end

.respond_successObject



554
# File 'lib/goat.rb', line 554

def respond_success; [200, {}, ['ok']]; end

Instance Method Details

#erb(name, opts = {}, &blk) ⇒ Object



682
683
684
685
686
# File 'lib/goat.rb', line 682

def erb(name, opts={}, &blk)
  e = ERBRunner.new(@req, @response, @params)
  e.delegate = self
  e.erb(name, {:locals => {:page => nil}}.merge(opts), &blk)
end

#paramsObject



675
# File 'lib/goat.rb', line 675

def params; @params; end

#requestObject



674
# File 'lib/goat.rb', line 674

def request; @req; end

#respond_with_hook(hook, *args) ⇒ Object



677
678
679
680
# File 'lib/goat.rb', line 677

def respond_with_hook(hook, *args)
  response.body = self.send(hook, *args) || ''
  response.finish
end

#responseObject



673
# File 'lib/goat.rb', line 673

def response; @response; end