MCPcopy
hub / github.com/google/mtail / CompileAndRun

Method CompileAndRun

internal/runtime/runtime.go:141–204  ·  view source on GitHub ↗

CompileAndRun compiles a program read from the input, starting execution if it succeeds. If an existing virtual machine of the same name already exists, the previous virtual machine is terminated and the new loaded over it. If the new program fails to compile, any existing virtual machine with the

(name string, input io.Reader)

Source from the content-addressed store, hash-verified

139// it. If the new program fails to compile, any existing virtual machine with
140// the same name remains running.
141func (r *Runtime) CompileAndRun(name string, input io.Reader) error {
142 glog.V(2).Infof("CompileAndRun %s", name)
143 var buf bytes.Buffer
144 tee := io.TeeReader(input, &buf)
145 hasher := sha256.New()
146 if _, err := io.Copy(hasher, tee); err != nil {
147 ProgLoadErrors.Add(name, 1)
148 return errors.Wrapf(err, "hashing failed for %q", name)
149 }
150 contentHash := hasher.Sum(nil)
151 r.handleMu.RLock()
152 vh, ok := r.handles[name]
153 r.handleMu.RUnlock()
154 if ok && bytes.Equal(vh.contentHash, contentHash) {
155 glog.V(1).Infof("contents match, not recompiling %q", name)
156 return nil
157 }
158 obj, errs := r.c.Compile(name, &buf)
159 if errs != nil {
160 ProgLoadErrors.Add(name, 1)
161 return errors.Errorf("compile failed for %s:\n%s", name, errs)
162 }
163 if obj == nil {
164 ProgLoadErrors.Add(name, 1)
165 return errors.Errorf("internal error: compilation failed for %s: no program returned, but no errors", name)
166 }
167 v := vm.New(name, obj, r.syslogUseCurrentYear, r.overrideLocation, r.logRuntimeErrors, r.trace)
168
169 if r.dumpBytecode {
170 glog.Info("Dumping program objects and bytecode\n", v.DumpByteCode())
171 }
172
173 // Load the metrics from the compilation into the global metric storage for export.
174 for _, m := range v.Metrics {
175 if !m.Hidden {
176 if r.omitMetricSource {
177 m.Source = ""
178 }
179 err := r.ms.Add(m)
180 if err != nil {
181 return err
182 }
183 }
184 }
185
186 ProgLoads.Add(name, 1)
187 glog.Infof("Loaded program %s", name)
188
189 if r.compileOnly {
190 return nil
191 }
192
193 r.handleMu.Lock()
194 defer r.handleMu.Unlock()
195 // Terminates the existing vm.
196 if handle, ok := r.handles[name]; ok {
197 close(handle.lines)
198 }

Callers 3

LoadProgramMethod · 0.95
TestCompileAndRunFunction · 0.80
TestRuntimeEndToEndFunction · 0.80

Calls 5

NewFunction · 0.92
CompileMethod · 0.80
DumpByteCodeMethod · 0.80
AddMethod · 0.45
RunMethod · 0.45

Tested by 2

TestCompileAndRunFunction · 0.64
TestRuntimeEndToEndFunction · 0.64