Module: Tupelo

Defined in:
lib/tupelo/app.rb,
lib/tupelo/client.rb,
lib/tupelo/version.rb,
lib/tupelo/archiver.rb,
lib/tupelo/app/remote.rb,
lib/tupelo/app/builder.rb,
lib/tupelo/client/common.rb,
lib/tupelo/client/scheduler.rb

Defined Under Namespace

Classes: AppBuilder, Archiver, Client

Constant Summary collapse

VERSION =
"0.22"

Class Method Summary collapse

Class Method Details

.application(argv: nil, services_file: nil, blob_type: nil, seqd_addr: {}, cseqd_addr: {}, arcd_addr: {}, **opts, &block) ⇒ Object

blob_type: ‘msgpack’ # the default blob_type: ‘marshal’ # if you need to pass general ruby objects blob_type: ‘yaml’ # less general ruby objects, but cross-language blob_type: ‘json’ # more portable than yaml, but more restrictive



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/tupelo/app.rb', line 54

def self.application argv: nil,
      services_file: nil, blob_type: nil,
      seqd_addr: {}, cseqd_addr: {}, arcd_addr: {}, **opts, &block

  unless argv
    argv, h = parse_args(ARGV)
    opts.merge! h
  end

  log_level = opts[:log_level]
  verbose = opts[:verbose]
  blob_type = blob_type || "msgpack"
  enable_trace = opts[:trace]
  tunnel_default = !!opts[:tunnel]
  persist_dir = opts[:persist_dir]

  if not services_file and argv[0] !~ /^-/ ## hacky
    services_file = argv.shift
  end

  ez_opts = {
    services_file: services_file,
    interactive: $stdin.isatty
  }

  EasyServe.start ez_opts do |ez|
    log = ez.log
    log.level = log_level
    log.formatter = nil if verbose
    log.progname = File.basename($0)
    owns_services = false

    ez.start_services do
      owns_services = true

      arc_to_seq_sock, seq_to_arc_sock = UNIXSocket.pair
      arc_to_cseq_sock, cseq_to_arc_sock = UNIXSocket.pair

      ez.service :seqd, **seqd_addr do |sv|
        require 'funl/message-sequencer'
        seq = Funl::MessageSequencer.new sv, seq_to_arc_sock, log: log,
          blob_type: blob_type
        seq.start
      end

      ez.service :cseqd, **cseqd_addr do |sv|
        require 'funl/client-sequencer'
        cseq = Funl::ClientSequencer.new sv, cseq_to_arc_sock, log: log
        cseq.start
      end

      ez.service :arcd, **arcd_addr do |sv|
        require 'tupelo/archiver'
        if persist_dir
          require 'tupelo/archiver/persistent-tuplestore'
          arc = Archiver.new sv, seq: arc_to_seq_sock,
                  tuplestore: Archiver::PersistentTupleStore,
                  persist_dir: persist_dir,
                  cseq: arc_to_cseq_sock, log: log
        else
          arc = Archiver.new sv, seq: arc_to_seq_sock,
                  tuplestore: Archiver::TupleStore,
                  cseq: arc_to_cseq_sock, log: log
        end
        arc.start
      end
    end

    app = AppBuilder.new(ez, argv: argv.dup,
        owns_services: owns_services, tunnel_default: tunnel_default)

    if enable_trace
      require 'tupelo/app/trace'
      app.start_trace
    end

    if owns_services
      ## optimize this away -- need lightweight client
      ## or (better) make subspaces a default even without using app
      app.local subscribe: nil do
        use_subspaces!
      end
    end

    if block
      if block.arity == 0
        app.instance_eval(&block)
      else
        yield app
      end
    else
      app
    end
  end
end

.parse_args(orig_argv) ⇒ Object

Returns [argv, opts], leaving orig_argv unmodified. The opts hash contains switches (and their arguments, if any) recognized by tupelo. The argv array contains all unrecognized arguments.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/tupelo/app.rb', line 9

def self.parse_args orig_argv
  argv = orig_argv.dup
  opts = {}

  opts[:log_level] =
    case
    when argv.delete("--debug"); Logger::DEBUG
    when argv.delete("--info");  Logger::INFO
    when argv.delete("--warn");  Logger::WARN
    when argv.delete("--error"); Logger::ERROR
    when argv.delete("--fatal"); Logger::FATAL
    else Logger::WARN
    end

  opts[:verbose] = argv.delete("-v")

  if i = argv.index("--persist-dir")
    argv.delete_at(i)
    opts[:persist_dir] = argv.delete_at(i)
  end

  %w{--marshal --yaml --json --msgpack}.each do |switch|
    s = argv.delete(switch) and
      opts[:blob_type] = s.delete("--")
  end

  opts[:trace] = argv.delete("--trace")
  opts[:tunnel] = argv.delete("--tunnel")

  [argv, opts]
end

.tcp_application(argv: nil, services_file: nil, blob_type: nil, seqd_addr: {}, cseqd_addr: {}, arcd_addr: {}, **opts, &block) ⇒ Object

same as application, but with tcp sockets the default



42
43
44
45
46
47
# File 'lib/tupelo/app.rb', line 42

def self.tcp_application argv: nil, services_file: nil, blob_type: nil,
      seqd_addr: {}, cseqd_addr: {}, arcd_addr: {}, **opts, &block
  seqd_addr[:proto] = cseqd_addr[:proto] = arcd_addr[:proto] = :tcp
  application argv: argv, services_file: services_file, blob_type: blob_type,
    seqd_addr: seqd_addr, cseqd_addr: cseqd_addr, arcd_addr: arcd_addr, &block
end