Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Concurreny Support #57

Open
jefree opened this issue Sep 19, 2017 · 4 comments
Open

Concurreny Support #57

jefree opened this issue Sep 19, 2017 · 4 comments

Comments

@jefree
Copy link

jefree commented Sep 19, 2017

Hi there, i'm just trying a kinda simple code that involves go routines:

// main.go

package main

import (
  "github.com/mitchellh/go-mruby"
  "sync"
)

func main() {
  mrb := mruby.NewMrb()
  defer mrb.Close()

  var wg sync.WaitGroup

  for i := 1; i < 50000; i++ {
    wg.Add(1)

    go func() {
      mrb.LoadString("puts 'hola mundo'")
      wg.Done()
    }()
  }

  wg.Wait()

after doing go run main.go it starts to print the messages as expected but after a while it raise a fatal error:

fatal error: unexpected signal during runtime execution
fatal error: schedule: holding locks
panic during panic
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1357b900160 pc=0x55e9799579c9]

it seems like at some point something really bad is happening inside the Mrb struct, and it just starts crashing over and over again.

my go version is go1.7.4 linux/amd64 running in a Debian 9.1 (stretch)

@erikh
Copy link
Collaborator

erikh commented Sep 19, 2017 via email

@erikh
Copy link
Collaborator

erikh commented Sep 19, 2017 via email

@erikh
Copy link
Collaborator

erikh commented Sep 14, 2018

did this ever get fixed?

@erikh
Copy link
Collaborator

erikh commented Sep 16, 2018

ok, this actually ends up being a problem with the mrb object not being re-entrant... in mruby itself when entered externally with load_string. I'm not entirely certain this would work with mruby without golang either.

Conversely, this code executes just fine, allocating a single interpreter per goroutine:

// main.go

package main

import (
	"sync"

	"github.com/mitchellh/go-mruby"
)

func main() {

	var wg sync.WaitGroup

	for i := 1; i < 50000; i++ {
		wg.Add(1)

		go func() {
			mrb := mruby.NewMrb()
			defer mrb.Close()
			mrb.LoadString("puts 'hola mundo'")
			wg.Done()
		}()
	}

	wg.Wait()
}

since this is a resolution you can take today, I strongly suggest you take it. You can wrap mutual accesses with mutex locks of your own devising, allowing you to load code sequentially from different goroutines. Alternatively, you can feed that code through a channel and load it serially.

we can do this as well; I just need to think of the situations that can go wrong by embedding a mutex in the struct around these operations, and whether or not it's better to just say "deal with it yourself". If other maintainers have a solution they like, please chime in.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants