Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugins implode upon errors when developing locally #132

Closed
ryanleecode opened this issue May 12, 2019 · 13 comments
Closed

Plugins implode upon errors when developing locally #132

ryanleecode opened this issue May 12, 2019 · 13 comments
Labels
bug Something isn't working

Comments

@ryanleecode
Copy link

If you try to develop a plugin locally and the method you invoke returns an error, it your application will crash. When to invoke the same plugin that is versioned, you won't crash.

Also interestingly, I am unable to catch errors when invoking platform methods using try/catch.

Flutter version

Flutter 1.5.8 • channel dev • https://github.com/flutter/flutter.git
Framework • revision 0ba67226ee (3 weeks ago) • 2019-04-24 17:18:28 -0700
Engine • revision c63d1cf9c9
Tools • Dart 2.3.0 (build 2.3.0-dev.0.1 1f1592edce)

Plugin version

github.com/go-flutter-desktop/plugins/shared_preferences v0.4.0

Go.mod file

module github.com/drdgvhbh/gitone/desktop

go 1.12

require (
	github.com/go-flutter-desktop/go-flutter v0.15.0
	github.com/go-flutter-desktop/plugins/shared_preferences v0.4.0
	github.com/pkg/errors v0.8.1
)

replace github.com/go-flutter-desktop/plugins/shared_preferences => /home/drd/go/src/github.com/go-flutter-desktop/plugins/shared_preferences

Golang errors (Optional)

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f65fe420636]

runtime stack:
runtime.throw(0x607a46, 0x2a)
        /usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:374 +0x4a9

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x593120, 0xc0000abc30, 0x0)
        /usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc0000abc00 sp=0xc0000abbc8 pc=0x40dc4b
github.com/go-flutter-desktop/go-flutter/embedder._Cfunc_FlutterEngineSendPlatformMessageResponse(0x22ea860, 0x23c6640, 0x22e95c0, 0x1f, 0x0)
        _cgo_gotypes.go:274 +0x4d fp=0xc0000abc30 sp=0xc0000abc00 pc=0x4f638d
github.com/go-flutter-desktop/go-flutter/embedder.(*FlutterEngine).SendPlatformMessageResponse.func1(0xc000120000, 0x23c6640, 0xc0000c4080, 0x1f, 0x40, 0xc000000000)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/embedder/embedder.go:244 +0xe6 fp=0xc0000abc80 sp=0xc0000abc30 pc=0x4f7fd6
github.com/go-flutter-desktop/go-flutter/embedder.(*FlutterEngine).SendPlatformMessageResponse(0xc000120000, 0x23c6640, 0xc0000c4080, 0x1f, 0x40, 0xc0000abd18)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/embedder/embedder.go:244 +0x53 fp=0xc0000abcc0 sp=0xc0000abc80 pc=0x4f75c3
github.com/go-flutter-desktop/go-flutter.responseSender.Send.func1()
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/messenger.go:108 +0x5b fp=0xc0000abd28 sp=0xc0000abcc0 pc=0x532b8b
github.com/go-flutter-desktop/go-flutter/internal/tasker.(*Tasker).ExecuteTasks(0xc00009c090)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/internal/tasker/tasker.go:39 +0x33 fp=0xc0000abd70 sp=0xc0000abd28 pc=0x4f8923
github.com/go-flutter-desktop/go-flutter.(*Application).Run(0xc0000a4210, 0x0, 0x0)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/application.go:192 +0x97e fp=0xc0000abed0 sp=0xc0000abd70 pc=0x52dbce
github.com/go-flutter-desktop/go-flutter.Run(0xc000086210, 0x5, 0x6, 0x3, 0xc0000abf78)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/application.go:23 +0x4d fp=0xc0000abf00 sp=0xc0000abed0 pc=0x52cf0d
main.main()
        /home/drd/Documents/Projects/GitOne/gitone/desktop/cmd/main.go:24 +0x189 fp=0xc0000abf98 sp=0xc0000abf00 pc=0x581669
runtime.main()
        /usr/local/go/src/runtime/proc.go:200 +0x20c fp=0xc0000abfe0 sp=0xc0000abf98 pc=0x43744c
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000abfe8 sp=0xc0000abfe0 pc=0x4615e1

goroutine 19 [select]:
github.com/syndtr/goleveldb/leveldb/util.(*BufferPool).drain(0xc00012a000)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/util/buffer_pool.go:206 +0x121
created by github.com/syndtr/goleveldb/leveldb/util.NewBufferPool
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/util/buffer_pool.go:237 +0x176

goroutine 35 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).compactionError(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:90 +0xcd
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:142 +0x40f

goroutine 36 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_state.go:101 +0xf6
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:143 +0x431

goroutine 37 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).tCompaction(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:825 +0x23a
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:149 +0x585

goroutine 38 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mCompaction(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:762 +0x12e
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:150 +0x5a7

goroutine 6 [chan receive]:
github.com/go-flutter-desktop/go-flutter/internal/tasker.(*Tasker).Do(0xc00009c090, 0xc0000a0100)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/internal/tasker/tasker.go:31 +0x8d
created by github.com/go-flutter-desktop/go-flutter.responseSender.Send
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/messenger.go:107 +0xe0
Lost connection to device.

Steps to Reproduce

  1. Bootstrap a go-flutter desktop application
  2. Have github.com/go-flutter-desktop/plugins/shared_preferences in your go source folder
  3. Add github.com/go-flutter-desktop/plugins/shared_preferences v0.4.0
  4. Remap the shared_preferences package using replace github.com/go-flutter-desktop/plugins/shared_preferences => /home/drd/go/src/github.com/go-flutter-desktop/plugins/shared_preferences
  5. Add a button to invoke the method. The code below is sufficient.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class InvokeButton extends StatelessWidget {
  static const platform =
      const MethodChannel('plugins.flutter.io/shared_preferences');

  @override
  Widget build(BuildContext context) {
    return MaterialButton(
        child: Text("Invoke me"),
        onPressed: () async => await _invoke());
  }

  Future<void> _invoke() async {
    debugPrint('testing');
    try {
      var result = await platform.invokeMethod("remove", "i am a bad argument");
      debugPrint(result);
    } catch (err) {
      debugPrint("Error" + err);
    }
  }
}
  1. Click on the button in your flutter desktop app. You will crash. No errors will be printed.
@pchampio
Copy link
Member

pchampio commented May 17, 2019

Regarding

unable to catch errors when invoking platform methods using try/catch.

I think it is related to what is described here.


And for

If you try to develop a plugin locally and the method you invoke returns an error, it your application will crash. When to invoke the same plugin that is versioned, you won't crash.

I cannot reproduce the error described error, on my pc... it dosn't crash.
I am getting the folowing output (The error is expected since there is a misuse of a plugin platform message)

flutter: testing
go-flutter: no method handler registered for method 'SystemSound.play' on channel 'flutter/platform'
go-flutter: recovered from panic while handling call for method 'remove' on channel 'plugins.flutter.io/shared_preferences': interface conversion: interface {} is string, not map[interface {}]interface {}
goroutine 41 [running]:
runtime/debug.Stack(0xcd, 0x0, 0x0)
        /usr/lib/go/src/runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
        /usr/lib/go/src/runtime/debug/stack.go:16 +0x22
github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleMethodCall.func1(0xc000564b48, 0x6, 0x5a9080, 0xc0000132b0, 0xc000140190)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:155 +0x159
panic(0x5b9a80, 0xc000592180)
        /usr/lib/go/src/runtime/panic.go:522 +0x1b5
github.com/go-flutter-desktop/plugins/shared_preferences.(*SharedPreferencesPlugin).handleRemove(0xc000088240, 0x5a9080, 0xc0000132b0, 0x45da90, 0x28, 0xc000569da0, 0x0)
        /home/drakirus/lab/go/src/github.com/go-flutter-desktop/plugins/shared_preferences/plugin.go:106 +0x1e0
github.com/go-flutter-desktop/go-flutter/plugin.MethodHandlerFunc.HandleMethod(0xc000012360, 0x5a9080, 0xc0000132b0, 0x6, 0x5a9080, 0xc0000132b0, 0xc000140190)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-handler.go:17 +0x3a
github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleMethodCall(0xc000140190, 0x627f00, 0xc000012360, 0xc000564b48, 0x6, 0x5a9080, 0xc0000132b0, 0x627ea0, 0xc0005943c0)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:159 +0xc7
created by github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleChannelMessage
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:143 +0x261

Using the folowing go.mod

module github.com/go-flutter-desktop/examples/pointer_demo/desktop

go 1.12

require (
	github.com/go-flutter-desktop/go-flutter v0.16.0
	github.com/go-flutter-desktop/plugins/shared_preferences v0.4.0
	github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1
	github.com/mitchellh/go-homedir v1.1.0 // indirect
	github.com/pkg/errors v0.8.1
	github.com/stretchr/objx v0.2.0 // indirect
)

replace github.com/go-flutter-desktop/plugins/shared_preferences => /home/drakirus/lab/go/src/github.com/go-flutter-desktop/plugins/shared_preferences

@davidmartos96
Copy link
Contributor

I am experiencing this same crash when returning some error from the Go plugin side. I am also using the replace keyword to develop the plugin locally.
Are there any workarounds to overcome this issue?

@davidmartos96
Copy link
Contributor

I digged a bit in the source code and I found this in method-channel.go

func (m *MethodChannel) handleMethodCall(handler MethodHandler, methodCall MethodCall, responseSender ResponseSender) {
	defer func() {
		p := recover()
		if p != nil {
			fmt.Printf("go-flutter: recovered from panic while handling call for method '%s' on channel '%s': %v\n", methodCall.Method, m.channelName, p)
			debug.PrintStack()
		}
	}()

	reply, err := handler.HandleMethod(methodCall.Arguments)
	if err != nil {
		fmt.Printf("go-flutter: handler for method '%s' on channel '%s' returned an error: %v\n", methodCall.Method, m.channelName, err)
		binaryReply, err := m.methodCodec.EncodeErrorEnvelope("error", err.Error(), nil)
		if err != nil {
			fmt.Printf("go-flutter: failed to encode error envelope for method '%s' on channel '%s', error: %v\n", methodCall.Method, m.channelName, err)
		}
		responseSender.Send(binaryReply)
	}

	binaryReply, err := m.methodCodec.EncodeSuccessEnvelope(reply)
	if err != nil {
		fmt.Printf("go-flutter: failed to encode success envelope for method '%s' on channel '%s', error: %v\n", methodCall.Method, m.channelName, err)
	}
	responseSender.Send(binaryReply)
}

Shouldn't the last block be in an else statement? If handler.HandleMethod returns an error, 2 responses are being sent, which causes the error from this issue. I tried it with the else and it works as expected.
Is it a bug?

@pchampio
Copy link
Member

pchampio commented Jun 29, 2019

@davidmartos96 I think you are right!
It does look like a bug!
Can you craft a quick pull request?

@davidmartos96
Copy link
Contributor

@Drakirus I just created a PR #174

@pchampio
Copy link
Member

pchampio commented Jun 30, 2019

I was able to reproduce the error.

First of:

var result = await platform.invokeMethod("remove", "i am a bad argument");

Will generate a panic since this cast isn't correct.
The following output is to be expected since there is a misuse of a plugin.

flutter: testing
go-flutter: no method handler registered for method 'SystemSound.play' on channel 'flutter/platform'
go-flutter: recovered from panic while handling call for method 'remove' on channel 'plugins.flutter.io/shared_preferences': interface conversion: interface {} is string, not map[interface {}]interface {}
goroutine 41 [running]:
runtime/debug.Stack(0xcd, 0x0, 0x0)
        /usr/lib/go/src/runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
        /usr/lib/go/src/runtime/debug/stack.go:16 +0x22
github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleMethodCall.func1(0xc000564b48, 0x6, 0x5a9080, 0xc0000132b0, 0xc000140190)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:155 +0x159
panic(0x5b9a80, 0xc000592180)
        /usr/lib/go/src/runtime/panic.go:522 +0x1b5
github.com/go-flutter-desktop/plugins/shared_preferences.(*SharedPreferencesPlugin).handleRemove(0xc000088240, 0x5a9080, 0xc0000132b0, 0x45da90, 0x28, 0xc000569da0, 0x0)
        /home/drakirus/lab/go/src/github.com/go-flutter-desktop/plugins/shared_preferences/plugin.go:106 +0x1e0
github.com/go-flutter-desktop/go-flutter/plugin.MethodHandlerFunc.HandleMethod(0xc000012360, 0x5a9080, 0xc0000132b0, 0x6, 0x5a9080, 0xc0000132b0, 0xc000140190)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-handler.go:17 +0x3a
github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleMethodCall(0xc000140190, 0x627f00, 0xc000012360, 0xc000564b48, 0x6, 0x5a9080, 0xc0000132b0, 0x627ea0, 0xc0005943c0)
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:159 +0xc7
created by github.com/go-flutter-desktop/go-flutter/plugin.(*MethodChannel).handleChannelMessage
        /home/drakirus/lab/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.16.0/plugin/method-channel.go:143 +0x261

go-flutter will recover the panic and resume normal execution.

I was unable to reproduce the

golang error proposed by @drdgvhbh
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7f65fe420636]

runtime stack:
runtime.throw(0x607a46, 0x2a)
        /usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:374 +0x4a9

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x593120, 0xc0000abc30, 0x0)
        /usr/local/go/src/runtime/cgocall.go:128 +0x5b fp=0xc0000abc00 sp=0xc0000abbc8 pc=0x40dc4b
github.com/go-flutter-desktop/go-flutter/embedder._Cfunc_FlutterEngineSendPlatformMessageResponse(0x22ea860, 0x23c6640, 0x22e95c0, 0x1f, 0x0)
        _cgo_gotypes.go:274 +0x4d fp=0xc0000abc30 sp=0xc0000abc00 pc=0x4f638d
github.com/go-flutter-desktop/go-flutter/embedder.(*FlutterEngine).SendPlatformMessageResponse.func1(0xc000120000, 0x23c6640, 0xc0000c4080, 0x1f, 0x40, 0xc000000000)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/embedder/embedder.go:244 +0xe6 fp=0xc0000abc80 sp=0xc0000abc30 pc=0x4f7fd6
github.com/go-flutter-desktop/go-flutter/embedder.(*FlutterEngine).SendPlatformMessageResponse(0xc000120000, 0x23c6640, 0xc0000c4080, 0x1f, 0x40, 0xc0000abd18)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/embedder/embedder.go:244 +0x53 fp=0xc0000abcc0 sp=0xc0000abc80 pc=0x4f75c3
github.com/go-flutter-desktop/go-flutter.responseSender.Send.func1()
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/messenger.go:108 +0x5b fp=0xc0000abd28 sp=0xc0000abcc0 pc=0x532b8b
github.com/go-flutter-desktop/go-flutter/internal/tasker.(*Tasker).ExecuteTasks(0xc00009c090)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/internal/tasker/tasker.go:39 +0x33 fp=0xc0000abd70 sp=0xc0000abd28 pc=0x4f8923
github.com/go-flutter-desktop/go-flutter.(*Application).Run(0xc0000a4210, 0x0, 0x0)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/application.go:192 +0x97e fp=0xc0000abed0 sp=0xc0000abd70 pc=0x52dbce
github.com/go-flutter-desktop/go-flutter.Run(0xc000086210, 0x5, 0x6, 0x3, 0xc0000abf78)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/application.go:23 +0x4d fp=0xc0000abf00 sp=0xc0000abed0 pc=0x52cf0d
main.main()
        /home/drd/Documents/Projects/GitOne/gitone/desktop/cmd/main.go:24 +0x189 fp=0xc0000abf98 sp=0xc0000abf00 pc=0x581669
runtime.main()
        /usr/local/go/src/runtime/proc.go:200 +0x20c fp=0xc0000abfe0 sp=0xc0000abf98 pc=0x43744c
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000abfe8 sp=0xc0000abfe0 pc=0x4615e1

goroutine 19 [select]:
github.com/syndtr/goleveldb/leveldb/util.(*BufferPool).drain(0xc00012a000)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/util/buffer_pool.go:206 +0x121
created by github.com/syndtr/goleveldb/leveldb/util.NewBufferPool
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/util/buffer_pool.go:237 +0x176

goroutine 35 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).compactionError(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:90 +0xcd
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:142 +0x40f

goroutine 36 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_state.go:101 +0xf6
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:143 +0x431

goroutine 37 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).tCompaction(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:825 +0x23a
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:149 +0x585

goroutine 38 [select]:
github.com/syndtr/goleveldb/leveldb.(*DB).mCompaction(0xc0001241a0)
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db_compaction.go:762 +0x12e
created by github.com/syndtr/goleveldb/leveldb.openDB
        /home/drd/go/pkg/mod/github.com/syndtr/goleveldb@v1.0.0/leveldb/db.go:150 +0x5a7

goroutine 6 [chan receive]:
github.com/go-flutter-desktop/go-flutter/internal/tasker.(*Tasker).Do(0xc00009c090, 0xc0000a0100)
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/internal/tasker/tasker.go:31 +0x8d
created by github.com/go-flutter-desktop/go-flutter.responseSender.Send
        /home/drd/go/pkg/mod/github.com/go-flutter-desktop/go-flutter@v0.15.0/messenger.go:107 +0xe0
Lost connection to device.
and I kind of let the issue aside 👎

Thanks to @davidmartos96 this issue was fixed.
The error wasn't about misuse of plugins but about errors thrown by plugins.
The regression was introduced during the v0.11.0 release. The handleMethodCall function should return earlier.

I should of try to dig a little bit deeper when I looked at the issue (by asking questions). This error was serious, and I didn't realized,.. my bad.

@pchampio
Copy link
Member

Ohh,
You are now able to catch PlatformException using try/catch!

@davidmartos96
Copy link
Contributor

@Drakirus I came across this issue while porting a plugin that threw some handled errors from the native side. Returning nil, err wasn't working correctly...

@pchampio
Copy link
Member

👍
Just out of curiosity, what is the plugin you are porting to go-flutter?

@davidmartos96
Copy link
Contributor

davidmartos96 commented Jun 30, 2019

@Drakirus It is sqflite. I almost have it, although I don't really know how to make it behave the same way as the iOS and Android implementations. In Android it uses Handler.post(runnable) to make some operation in the background and then it posts the response back to the main thread to call Result.success(someResult). The handler function it quickly finishes because it leaves the operation to the background thread. When running in Go, the handle functions for each DB operation are blocking...

@pchampio
Copy link
Member

When running in Go, the handle functions for each DB operation are blocking...

If you are using HandleFuncSync the operation will block the Main Thread.
But using HandleFunc, the operation are run on a background thread.

@davidmartos96
Copy link
Contributor

@Drakirus Yes, I was already using HandleFunc. I found the issue though. I was comparing the performance of the sqlite library on the android emulator vs go-flutter. It looks like the encoding and decoding performance of the platform calls is much worse in go-flutter.

1 INSERT (time since the call to invokeMethod in Dart until the reply is received in Dart)
Android emulator -> 1 ms
Go Flutter -> 30 ms

Quite different performance right?

The time it takes to make the actual INSERT measured in the native side is 100 us in both platforms.

Is this a known limitation of the project? Awesome project BTW :)

@pchampio
Copy link
Member

pchampio commented Jun 30, 2019

@davidmartos96 thanks for the feedback.
The encoding and decoding performance should be as good as on Android, Golang is Fast.

I'm pretty sure the 30ms comes from the MainLoop.

The flutter engine team added FlutterEngineFlushPendingTasksNow as a workaround for embedders to flush tasks (platform messages) on threads where the engine didn't own the message loop (or couldn't interact with the same as is the case on Android and iOS).

On go-flutter, we could use PollEvents to have an instant feedback platform messages, but that would result in high CPU load.
In order to reduce CPU load we choose to wait 16ms in order to get the 60fps-ish iterations while having the possibility to fetch platforms messages when no pending frames are to be swapped.
I assume the 30ms delay you are experiencing comes from 2 loop cycles, one to get the platform message and issuing the task into a specific goroutine; and one to return the message to Dart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

4 participants