| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of service; | 5 part of service; |
| 6 | 6 |
| 7 // Some value smaller than the object ring, so requesting a large array | 7 // Some value smaller than the object ring, so requesting a large array |
| 8 // doesn't result in an expired ref because the elements lapped it in the | 8 // doesn't result in an expired ref because the elements lapped it in the |
| 9 // object ring. | 9 // object ring. |
| 10 const int kDefaultFieldLimit = 100; | 10 const int kDefaultFieldLimit = 100; |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 _controllers.remove(controller); | 582 _controllers.remove(controller); |
| 583 if (_controllers.isEmpty) { | 583 if (_controllers.isEmpty) { |
| 584 assert(_listenFuture != null); | 584 assert(_listenFuture != null); |
| 585 _listenFuture = null; | 585 _listenFuture = null; |
| 586 _cancelFuture = _vm._streamCancel(streamId); | 586 _cancelFuture = _vm._streamCancel(streamId); |
| 587 _cancelFuture.then((_) { | 587 _cancelFuture.then((_) { |
| 588 if (_controllers.isEmpty) { | 588 if (_controllers.isEmpty) { |
| 589 // No new listeners showed up during cancelation. | 589 // No new listeners showed up during cancelation. |
| 590 _onDone(); | 590 _onDone(); |
| 591 } | 591 } |
| 592 }).catchError((e) { |
| 593 /* ignore */ |
| 592 }); | 594 }); |
| 593 } | 595 } |
| 594 // No need to wait for _cancelFuture here. | 596 // No need to wait for _cancelFuture here. |
| 595 return new Future.value(null); | 597 return new Future.value(null); |
| 596 } | 598 } |
| 597 | 599 |
| 598 Future<Stream> addStream() async { | 600 Future<Stream> addStream() async { |
| 599 var controller; | 601 var controller; |
| 600 controller = new StreamController( | 602 controller = new StreamController( |
| 601 onCancel:() => _cancelController(controller)); | 603 onCancel:() => _cancelController(controller)); |
| 602 _controllers.add(controller); | 604 _controllers.add(controller); |
| 603 if (_cancelFuture != null) { | 605 if (_cancelFuture != null) { |
| 604 await _cancelFuture; | 606 try { |
| 607 await _cancelFuture; |
| 608 } on NetworkRpcException catch (_) { /* ignore */ } |
| 605 } | 609 } |
| 606 if (_listenFuture == null) { | 610 if (_listenFuture == null) { |
| 607 _listenFuture = _vm._streamListen(streamId); | 611 _listenFuture = _vm._streamListen(streamId); |
| 608 } | 612 } |
| 609 await _listenFuture; | 613 try { |
| 614 await _listenFuture; |
| 615 } on NetworkRpcException catch (_) { /* ignore */ } |
| 610 return controller.stream; | 616 return controller.stream; |
| 611 } | 617 } |
| 612 | 618 |
| 613 void addEvent(ServiceEvent event) { | 619 void addEvent(ServiceEvent event) { |
| 614 for (var controller in _controllers) { | 620 for (var controller in _controllers) { |
| 615 controller.add(event); | 621 controller.add(event); |
| 616 } | 622 } |
| 617 } | 623 } |
| 618 } | 624 } |
| 619 | 625 |
| 620 /// State for a VM being inspected. | 626 /// State for a VM being inspected. |
| 621 abstract class VM extends ServiceObjectOwner implements M.VM { | 627 abstract class VM extends ServiceObjectOwner implements M.VM { |
| 622 VM get vm => this; | 628 VM get vm => this; |
| 623 Isolate get isolate => null; | 629 Isolate get isolate => null; |
| 624 | 630 |
| 625 // TODO(turnidge): The connection should not be stored in the VM object. | 631 // TODO(turnidge): The connection should not be stored in the VM object. |
| 626 bool get isDisconnected; | 632 bool get isDisconnected; |
| 633 bool get isConnected; |
| 627 | 634 |
| 628 // Used for verbose logging. | 635 // Used for verbose logging. |
| 629 bool verbose = false; | 636 bool verbose = false; |
| 630 | 637 |
| 631 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. | 638 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. |
| 632 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 639 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
| 633 final Map<String,Isolate> _isolateCache = <String,Isolate>{}; | 640 final Map<String,Isolate> _isolateCache = <String,Isolate>{}; |
| 634 | 641 |
| 635 // The list of live isolates, ordered by isolate start time. | 642 // The list of live isolates, ordered by isolate start time. |
| 636 final List<Isolate> isolates = <Isolate>[]; | 643 final List<Isolate> isolates = <Isolate>[]; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 } | 813 } |
| 807 | 814 |
| 808 Future<ServiceObject> invokeRpc(String method, Map params) { | 815 Future<ServiceObject> invokeRpc(String method, Map params) { |
| 809 return invokeRpcNoUpgrade(method, params).then((Map response) { | 816 return invokeRpcNoUpgrade(method, params).then((Map response) { |
| 810 var obj = new ServiceObject._fromMap(this, response); | 817 var obj = new ServiceObject._fromMap(this, response); |
| 811 if ((obj != null) && obj.canCache) { | 818 if ((obj != null) && obj.canCache) { |
| 812 String objId = obj.id; | 819 String objId = obj.id; |
| 813 _cache.putIfAbsent(objId, () => obj); | 820 _cache.putIfAbsent(objId, () => obj); |
| 814 } | 821 } |
| 815 return obj; | 822 return obj; |
| 823 }).catchError((e) { |
| 824 return new Future.error(e); |
| 816 }); | 825 }); |
| 817 } | 826 } |
| 818 | 827 |
| 819 void _dispatchEventToIsolate(ServiceEvent event) { | 828 void _dispatchEventToIsolate(ServiceEvent event) { |
| 820 var isolate = event.isolate; | 829 var isolate = event.isolate; |
| 821 if (isolate != null) { | 830 if (isolate != null) { |
| 822 isolate._onEvent(event); | 831 isolate._onEvent(event); |
| 823 } | 832 } |
| 824 } | 833 } |
| 825 | 834 |
| 826 Future restart() { | 835 Future restart() { |
| 827 return invokeRpc('_restartVM', {}); | 836 return invokeRpc('_restartVM', {}); |
| 828 } | 837 } |
| 829 | 838 |
| 830 Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) async { | 839 Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) async { |
| 831 if (!loaded) { | 840 if (!loaded) { |
| 832 // The vm service relies on these events to keep the VM and | 841 // The vm service relies on these events to keep the VM and |
| 833 // Isolate types up to date. | 842 // Isolate types up to date. |
| 834 try { | 843 try { |
| 835 await listenEventStream(kVMStream, _dispatchEventToIsolate); | 844 await listenEventStream(kVMStream, _dispatchEventToIsolate); |
| 836 await listenEventStream(kIsolateStream, _dispatchEventToIsolate); | 845 await listenEventStream(kIsolateStream, _dispatchEventToIsolate); |
| 837 await listenEventStream(kDebugStream, _dispatchEventToIsolate); | 846 await listenEventStream(kDebugStream, _dispatchEventToIsolate); |
| 838 await listenEventStream(_kGraphStream, _dispatchEventToIsolate); | 847 await listenEventStream(_kGraphStream, _dispatchEventToIsolate); |
| 839 } on FakeVMRpcException catch (_) { | 848 } on FakeVMRpcException catch (_) { |
| 840 // ignore FakeVMRpcExceptions here. | 849 // ignore FakeVMRpcExceptions here. |
| 850 } on NetworkRpcException catch (_) { |
| 851 // ignore network errors here. |
| 841 } | 852 } |
| 842 } | 853 } |
| 843 return await invokeRpcNoUpgrade('getVM', {}); | 854 return await invokeRpcNoUpgrade('getVM', {}); |
| 844 } | 855 } |
| 845 | 856 |
| 846 Future setName(String newName) { | 857 Future setName(String newName) { |
| 847 return invokeRpc('setVMName', { 'name': newName }); | 858 return invokeRpc('setVMName', { 'name': newName }); |
| 848 } | 859 } |
| 849 | 860 |
| 850 Future<ServiceObject> getFlagList() { | 861 Future<ServiceObject> getFlagList() { |
| 851 return invokeRpc('getFlagList', {}); | 862 return invokeRpc('getFlagList', {}); |
| 852 } | 863 } |
| 853 | 864 |
| 854 Future<ServiceObject> _streamListen(String streamId) { | 865 Future<ServiceObject> _streamListen(String streamId) { |
| 855 Map params = { | 866 Map params = { |
| 856 'streamId': streamId, | 867 'streamId': streamId, |
| 857 }; | 868 }; |
| 858 return invokeRpc('streamListen', params); | 869 return invokeRpc('streamListen', params).catchError((e) { |
| 870 // Ignore network errors on stream listen. |
| 871 if (e is NetworkRpcException) { |
| 872 return null; |
| 873 } |
| 874 }); |
| 859 } | 875 } |
| 860 | 876 |
| 861 Future<ServiceObject> _streamCancel(String streamId) { | 877 Future<ServiceObject> _streamCancel(String streamId) { |
| 862 Map params = { | 878 Map params = { |
| 863 'streamId': streamId, | 879 'streamId': streamId, |
| 864 }; | 880 }; |
| 865 return invokeRpc('streamCancel', params); | 881 return invokeRpc('streamCancel', params).catchError((e) { |
| 882 // Ignore network errors on stream cancel. |
| 883 if (e is NetworkRpcException) { |
| 884 return null; |
| 885 } |
| 886 }); |
| 866 } | 887 } |
| 867 | 888 |
| 868 // A map from stream id to event stream state. | 889 // A map from stream id to event stream state. |
| 869 Map<String,_EventStreamState> _eventStreams = {}; | 890 Map<String,_EventStreamState> _eventStreams = {}; |
| 870 | 891 |
| 871 // Well-known stream ids. | 892 // Well-known stream ids. |
| 872 static const kVMStream = 'VM'; | 893 static const kVMStream = 'VM'; |
| 873 static const kIsolateStream = 'Isolate'; | 894 static const kIsolateStream = 'Isolate'; |
| 874 static const kTimelineStream = 'Timeline'; | 895 static const kTimelineStream = 'Timeline'; |
| 875 static const kDebugStream = 'Debug'; | 896 static const kDebugStream = 'Debug'; |
| 876 static const kGCStream = 'GC'; | 897 static const kGCStream = 'GC'; |
| 877 static const kStdoutStream = 'Stdout'; | 898 static const kStdoutStream = 'Stdout'; |
| 878 static const kStderrStream = 'Stderr'; | 899 static const kStderrStream = 'Stderr'; |
| 879 static const _kGraphStream = '_Graph'; | 900 static const _kGraphStream = '_Graph'; |
| 880 | 901 |
| 881 /// Returns a single-subscription Stream object for a VM event stream. | 902 /// Returns a single-subscription Stream object for a VM event stream. |
| 882 Future<Stream> getEventStream(String streamId) async { | 903 Future<Stream> getEventStream(String streamId) async { |
| 883 var eventStream = _eventStreams.putIfAbsent( | 904 var eventStream = _eventStreams.putIfAbsent( |
| 884 streamId, () => new _EventStreamState( | 905 streamId, () => new _EventStreamState( |
| 885 this, streamId, () => _eventStreams.remove(streamId))); | 906 this, streamId, () => _eventStreams.remove(streamId))); |
| 886 return eventStream.addStream(); | 907 Stream stream = await eventStream.addStream(); |
| 908 return stream; |
| 887 } | 909 } |
| 888 | 910 |
| 889 /// Helper function for listening to an event stream. | 911 /// Helper function for listening to an event stream. |
| 890 Future<StreamSubscription> listenEventStream(String streamId, | 912 Future<StreamSubscription> listenEventStream(String streamId, |
| 891 Function function) async { | 913 Function function) async { |
| 892 var stream = await getEventStream(streamId); | 914 var stream = await getEventStream(streamId); |
| 893 return stream.listen(function); | 915 return stream.listen(function); |
| 894 } | 916 } |
| 895 | 917 |
| 896 /// Force the VM to disconnect. | 918 /// Force the VM to disconnect. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 | 1002 |
| 981 // Always connected. | 1003 // Always connected. |
| 982 Future _onConnect; | 1004 Future _onConnect; |
| 983 Future get onConnect { | 1005 Future get onConnect { |
| 984 if (_onConnect != null) { | 1006 if (_onConnect != null) { |
| 985 return _onConnect; | 1007 return _onConnect; |
| 986 } | 1008 } |
| 987 _onConnect = new Future.value(this); | 1009 _onConnect = new Future.value(this); |
| 988 return _onConnect; | 1010 return _onConnect; |
| 989 } | 1011 } |
| 1012 bool get isConnected => !isDisconnected; |
| 990 // Only complete when requested. | 1013 // Only complete when requested. |
| 991 Completer _onDisconnect = new Completer(); | 1014 Completer _onDisconnect = new Completer(); |
| 992 Future get onDisconnect => _onDisconnect.future; | 1015 Future get onDisconnect => _onDisconnect.future; |
| 993 bool get isDisconnected => _onDisconnect.isCompleted; | 1016 bool get isDisconnected => _onDisconnect.isCompleted; |
| 994 | 1017 |
| 995 Future<Map> invokeRpcRaw(String method, Map params) { | 1018 Future<Map> invokeRpcRaw(String method, Map params) { |
| 996 if (params.isEmpty) { | 1019 if (params.isEmpty) { |
| 997 params = null; | 1020 params = null; |
| 998 } | 1021 } |
| 999 var key = _canonicalizeUri(new Uri(path: method, queryParameters: params)); | 1022 var key = _canonicalizeUri(new Uri(path: method, queryParameters: params)); |
| (...skipping 3361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4361 var v = list[i]; | 4384 var v = list[i]; |
| 4362 if ((v is Map) && _isServiceMap(v)) { | 4385 if ((v is Map) && _isServiceMap(v)) { |
| 4363 list[i] = owner.getFromMap(v); | 4386 list[i] = owner.getFromMap(v); |
| 4364 } else if (v is List) { | 4387 } else if (v is List) { |
| 4365 _upgradeList(v, owner); | 4388 _upgradeList(v, owner); |
| 4366 } else if (v is Map) { | 4389 } else if (v is Map) { |
| 4367 _upgradeMap(v, owner); | 4390 _upgradeMap(v, owner); |
| 4368 } | 4391 } |
| 4369 } | 4392 } |
| 4370 } | 4393 } |
| OLD | NEW |