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.



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

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



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

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

.around_handlersObject



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

def around_handlers; @@around_handlers; end

.before(&blk) ⇒ Object



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

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

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



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

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



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

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

.error(&blk) ⇒ Object



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

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

.error_handlerObject



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

def error_handler; @@error_handler; end

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



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

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



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
622
# File 'lib/goat.rb', line 558

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



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

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

.not_found(&blk) ⇒ Object



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

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

.not_found_handlerObject



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

def not_found_handler; @@not_found_handler; end

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



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

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

.req_handlerObject



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

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

.respond_failedObject



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

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

.respond_successObject



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

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

Instance Method Details

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



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

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



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

def params; @params; end

#requestObject



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

def request; @req; end

#respond_with_hook(hook, *args) ⇒ Object



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

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

#responseObject



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

def response; @response; end