I am trying to use deferred libraries and the new async style, but it does not seem to work:
import 'dart:async';
import 'package:defer/library1.dart' deferred as lib1;
void main() async {
var b = await lib1.loadLibrary();
var a = new lib1.MyClass('Peter');
print(a.name);
}
The deferred library is never loaded and Dartium loading indication always stays on.
Am I doing something wrong?
For some reason using the async_await transformer was the issue. See https://github.com/dart-lang/async_await/issues/81
Related
here is a simple code that I use to learn isolate, I spawn twice, but the second spawn does not show anything, any mistake here? Thanks
import 'dart:isolate';
Future<void> main() async {
print('start');
await Isolate.spawn(echo, 'Dart');
await Isolate.spawn(echo, 'Flutter'); // why this 2nd spawn not showing up?
print('end');
}
void echo(msg) {
print(msg);
}
Your program quits before the Isolate has done its job. You can confirm this if you add
await Future.delayed(Duration(seconds: 1));
somewhere towards the end of your program.
Setting up Isolates is often a bit challenging, with all the SendPort stuff etc.
I like basic explanations of complex concepts in reactor all over the web, they are not particularly useful in production code, so following piece of code I wrote which sends a message to kafka using reactor kafka + spring boot:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.kafka.sender.KafkaSender;
import reactor.kafka.sender.SenderOptions;
import reactor.kafka.sender.SenderRecord;
import reactor.kafka.sender.SenderResult;
import java.util.Properties;
public class CallbackSender {
private ObjectMapper objectMapper;
private String topic;
private static final Logger log = LoggerFactory.getLogger(CallbackSender.class.getName());
private final KafkaSender<String, String> sender;
public CallbackSender(ObjectMapper objectMapper, Properties senderProps, String topic) {
this.sender = KafkaSender.create(SenderOptions.create(senderProps));
this.objectMapper = objectMapper;
this.topic = topic;
}
public Mono<SenderResult<String>> sendMessage(ProcessContext<? extends AbstractMessage> processContext) throws JsonProcessingException {
ProducerRecord<String, String> producerRecord = new ProducerRecord<>(topic,
objectMapper.writeValueAsString(processContext.getMessage()));
SenderRecord<String, String, String> senderRecord = SenderRecord.create(producerRecord, processContext.getId());
return sender.send(Flux.just(senderRecord))
.doOnError(e -> log.error("Send failed", e))
.last();
}
}
What I can't grasp in my mind is what exactly is the difference between calling this.sendMessage as .map vs .flatMap from the outer pipeline, so what for the explanation that map applying synchronous transformation to the emitted element if my synchronous function is not really doing anything synchronous apart from basic fields fetch?
Here Kafka sender is already reactive and async , so it doesn't matter which one I use? Is that correct assumption?
Is my code non-idiomatic?
Or for this particular it would be just a safe wrap of everything I am doing inside .sendMessage in .flatMap in case someone would add synchronous code in future, i.e. sugar-safety syntax.
My understanding is that .map will simply prepare pipeline in this case which returns Mono, and subscriber for outer calling pipeline will trigger entire domino effect, is that correct?
What I can't grasp in my mind is what exactly is the difference between calling this.sendMessage as .map vs .flatMap from the outer pipeline
map() applies a synchronous function (i.e. one "in-place" with no subscriptions or callbacks) and just returns the result as is. flatMap() applies an asynchronous transformer function, and unwraps the Publisher when done. So:
My understanding is that .map will simply prepare pipeline in this case which returns Mono, and subscriber for outer calling pipeline will trigger entire domino effect, is that correct?
Yes, that's correct (if by "domino effect" you mean that the returning mono will be subscribed to and its result returned.)
so what for the explanation that map applying synchronous transformation to the emitted element if my synchronous function is not really doing anything synchronous apart from basic fields fetch?
Quite simply, because that's what you've told it to do. There's nothing inherently asynchronous about setting up a publisher, just its execution once it's been subscribed to (which doesn't happen with a map() call.)
Being new to Dart/Flutter I am using this snippet to try and load a config.json file that I have stored in my assets folder. In trying to read this file, I am using models on the Dart language Futures documentation and in the Flutter docs on reading local text files:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
Future<List> loadAsset() async {
String raw = await rootBundle.loadString('assets/config.json');
List configData = json.decode(raw);
return configData;
}
Then, inside my class, I try to load the config into a List, like this:
Future<List> configData = loadAsset();
print(configData.toString());
// prints out: Instance of 'Future<List<dynamic>>'
The result of all this seems to work. Yet I can find no way of using the data I have loaded. Any effort to access elements in the List, e.g. configData[0] results in an error:
The following _CompileTimeError was thrown building
HomePage(dirty, state: HomePageState#b1af8):
'package:myapp/pages/home_page.dart': error:
line 64 pos 19: lib/pages/home_page.dart:64:19:
Error: The method '[]' isn't defined for the class
'dart.async::Future<dart.core::List<dynamic>>'.
Try correcting the name to the name of an existing method,
or defining a method named '[]'.
I would like to convert the configData Future into a normal object that I can read and pass around my app. I am able to do something very similar, and to get it to work inside a widget's build method, using a FutureBuilder and the DefaultAssetBundle thus...
DefaultAssetBundle
.of(context)
.loadString('assets/config.json')
...but I don't want the overhead of reloading the data inside all the widgets that need it. I would like to load inside a separate Dart package and have it available as a global configuration across all my app. Any pointers would be appreciated.
I have tried the suggestion by RĂ©mi Rousselet:
List configData = await loadAsset();
print(configData[0]);
In this case, I get a compiler error:
compiler message: lib/pages/home_page.dart:55:21: Error: Getter not found: 'await'.
compiler message: List configData = await loadAsset();
compiler message: ^^^^^
You can't do configData[0] as configData is not a List but a Future.
Instead, await the future to have access to the List inside
List configData = await loadAsset();
print(configData[0]);
You can only use await INSIDE async methods.
If you want to you your assets in entire application you want to load the asset in the main method similar like this.
void main() async {
StorageUtils.localStorage = await SharedPreferences.getInstance();
}
Now you can use localStorage synchronously in entire application and you don't need to deal with another asynchronous calls or load it again.
Different example, same principle.
I am having some difficulties making use of isolates in Dart. The first problem is I wanted to use dart:js to use a javascript library in one of my isolates. I tried with the following code:
void runCode(SendPort sendPort)
{
print("still ok...");
JsObject object = new JsObject(context['jsCode']);
print("still ok?");
}
void main()
{
ReceivePort receivePort = new ReceivePort();
JsObject object = new JsObject(context['jsCode']);
print("ok so far");
Isolate.spawn(runCode, receivePort.sendPort);
}
The code runs as far as "still ok..." in the runCode function and breaks when I try to use JsObject.
The second problem was I wanted to use the fileSystem API in the isolate. So I tried the following:
void runCode(SendPort sendPort)
{
window.requestFileSystem.then((FileSystem filesytem) => print('ok'));
}
void main()
{
ReceivePort receivePort = new ReceivePort();
Isolate.spawn(runCode, receivePort.sendPort);
}
This second example breaks when I reach the filesystem.
I have read: Dart : Isolate not working when using html import and from here it suggests that dart:html cannot be used in an isolate. Is this the reason why the filesystem API will not work? Is this the same case for dart:js? Or am I completely missing something?
Thanks for any help!
I've read somewhere that only the main thread has access to the DOM, which would cause any other JS action to fail if not in the main thread.
I have a general question on how to proper implement a logging system in dart. I can't find reliable doc on it. Is logging lib up to date ? Thx !
I think this is the simplest way to set it up
import 'package:logging/logging.dart' show Logger, Level; // every library
import 'package:quiver_log/log.dart'; // library containing main
final _log = new Logger('bwu_model.server.main'); // every library
// main
void main() {
Logger.root.level = Level.FINEST;
var appender = new PrintAppender(BASIC_LOG_FORMATTER);
appender.attachLogger(Logger.root);
// actual logging
_log.info('Pub session initialized.');
}