I am experiencing an infinite loop using an AsyncFunc in unordered mode.
It can be reproduced using the following code
import org.apache.flink.streaming.api.datastream.AsyncDataStream;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.async.AsyncFunction;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
public class AsyncTest {
#Test
public void test() throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<Integer> withTimestamps = env.fromCollection(Arrays.asList(1,2,3,4,5));
AsyncDataStream.unorderedWait(withTimestamps,
(AsyncFunction<Integer, String>) (input, collector) -> {
if (input == 3){
collector.collect(new RuntimeException("Test"));
return;
}
collector.collect(Collections.singleton("Ok"));
}, 10, TimeUnit.MILLISECONDS)
.returns(String.class)
.print();
env.execute("unit-test");
}
}
My guess would be that the UnorderedStreamElementQueue is the reason of the infinite loop.
It seems to add the StreamElementQueueEntry containing the failing future into its firstSet field but never removes it (as this failing future is not triggering the onCompleteHandler method).
Anyone knows if this could be right or if I am making a mistake in my code?
There is indeed a bug in the AsyncWaitOperator. The problem is that it does not react to results which are exceptions (user exceptions as well as timeout exceptions).
In the case of ordered waiting, this causes that exceptional results are only detected if another async result has been completed (without an exception).
In the case of unordered waiting, this causes that the StreamElementQueueEntry is never moved from the firstSet into the completedQueue.
There is an issue for this problem. It will hopefully be fixed in the next couple of days.
Related
I am using Apache Flink 1.16.0 version.
I am trying to do a simple CEP by printing the elements to the console
For any reason, there is nothing printed to the console, even the process finished with exit code 0.
Here is the code:
import org.apache.flink.cep.*;
import org.apache.flink.cep.functions.PatternProcessFunction;
import org.apache.flink.cep.pattern.Pattern;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> input = env.fromElements("adrian", "cincu", "diana", "sichitiu");
Pattern<String, ?> pattern = Pattern.begin("start");
PatternStream<String> patternStream = CEP.pattern(input, pattern);
DataStream<String> matches = patternStream.process(new PatternProcessFunction<String, String>() {
#Override
public void processMatch(Map<String, List<String>> map,
Context context,
Collector<String> collector) throws Exception {
collector.collect(map.get("start").toString());
}
});
matches.print();
env.execute("myjob");
}
}
Any clue?
I think the issue in this case is that Your pattern doesn't make sense. It will just start matching events, but there is no actual requirement for events to match the pattern, so every event (String in Your case) will match the same Pattern, this will cause the Pattern to stay open forever and never emit any actual data.
You may want to add some kind of requirements to make sure that pattern actually gets closed.
There is some info about how to define Patterns in the [docs].1
I am getting some sort of compilation error it seems.
I have ‘Common.java’ class inside ‘base’ package. It's a program for starting firefox driver. That, I have kept it in the separate package to make it a one time effort and modularity purpose.
I am calling this class file inside the child class ‘tc_01.java’. This TC_01.jave program is in another package ‘testing’. This TC_01.java file is actually accessing driver from Common.java and start the browser and try some login and logout actions.
My child class TC_01.java is showing me compilation error and Error Message on Mouse Hover is – > “field Common.driver is not visible”.
And, at Console : "java.lang.Error: Unresolved compilation problems:
The field Common.driver is not visible"
My Analysis: It seems TC_01.java file is not able to access the 'driver' from 'Common.java'.
But, I have already written 'extends' keyword for it to inherit the properties.
Please guide me. Thanks
Here is my code:->
package base;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class Common {
public FirefoxDriver driver;
#BeforeMethod
public void BM(){
System.setProperty(“webdriver.gecko.driver”,”D://Rajiv//Selenium//geckodriver.exe”);
driver = new FirefoxDriver();
driver.get(“http://automationpractice.com/index.php”);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#AfterMethod
public void CM(){
driver.close();
}
}
# Pakage – testing; Class – Tc_01.java
package testing;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import base.Common;
public class TC_01 extends Common{
public FirefoxDriver driver;`
#Test
public void TM(){
System.out.println(“Selenium Webdriver Script in Firefox browser using Gecko` `Driver | AutomationPractice.com PAGE LAUNCHED”);
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(“search_query_top”)));
try{
String expectedTitle = “My Store”;
System.out.println(“ExpectedTile = “+expectedTitle );
String actualTitle = driver.getTitle();
System.out.println(“The actual Title of the Page is = “+actualTitle);
Assert.assertEquals(actualTitle, expectedTitle);*/
System.out.println(“Control has reached here”);
driver.findElementByClassName(“login”).click(); // field common.driver is not visible
driver.findElementById(“email”).sendKeys(“*****#yahoo.com”);
driver.findElementById(“passwd”).sendKeys(“*****”);
driver.findElementById(“SubmitLogin”).click();
driver.findElementByClassName(“logout”).click();
System.out.println(“Sucessfully Logout from the Application”);
}catch (Exception e){
e.printStackTrace();
}
}
}
I was able to find the root cause for this issue.
It wasted my 3 days before i asked for help here in this forum.
As i had analysed initially, i had mentioned my driver properties in parent class and was accessing it in Child Class. There was some name mismatch. When it was trying to inherit the properties from parent, it was not accessible and giving me compilation error. I renamed the parent class name to the same name that i was giving while extending in Child Class. And, it worked.
Thanks again to all of you. It is such a wonderful forum to discuss your issue between each other and getting its resolution.
I'm building an app that should periodically capture the user's location (I'm looking for every 60 minutes), tracking the cities they've visited.
I first started off using the foreground location listener and it was perfect, it seems to fire every few minutes but I've put checks in place so that it only actually tracks a location if enough time has passed. When I switch to other apps it looks like the foreground listener will continue to fire for a period of time, and then just stop firing, which to me makes sense since I'm thinking the OS is backgrounding the app. At which point, I would expect the background listener to have been registered and wake the app when that listener is fired.
On to my question... I'm having trouble with the background location listener. I understand that it won't fire on simulator, but it's also not firing when I build debug (using built-in certificate) to my device. For the sake of this question I've distilled what my app is doing down to barebones, based off the example listed here: https://gist.github.com/shannah/86c739edac34216d3c4d
Just to be sure I tried switching the background listener to the standard foreground one (.setLocationListener(new BackgroundListener())), and running on the simulator, I can verify that my label gets updated with appropriate data.
I also had done some testing on my actual app where I would pop a dialog in the no-arg constructor to say the listener was initialized, and another dialog when locationUpdated was called. I was able to see the popup on init, but there was no dialog on locationUpdated, which led me to believe my device was never firing it.
The device I'm testing on is a Samsung S4 with Android 5.0.1 (Lollipop).
Here is the test application I wrote which closely mimics what my actual application is doing.
bglocation.java
package com.bglocation;
import java.util.List;
import com.codename1.io.Storage;
import com.codename1.location.LocationManager;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class bglocation {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World");
LocationManager.getLocationManager().setBackgroundLocationListener(BackgroundLocationListener.class);
String lastCheckin = (String)Storage.getInstance().readObject("LOCATION");
String label = "No checkins.";
if (lastCheckin != null) {
label = lastCheckin;
}
Label hiLabel = new Label("Last checkin: " + label);
hi.addComponent(hiLabel);
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
}
}
BackgroundLocationListener.java
package com.bglocation;
import java.util.Date;
import com.codename1.io.Storage;
import com.codename1.location.Location;
import com.codename1.location.LocationListener;
public class BackgroundLocationListener implements LocationListener {
#Override
public void locationUpdated(Location location) {
Storage.getInstance().writeObject("LOCATION", new Date().toString());
}
#Override
public void providerStateChanged(int newState) { }
}
The background listener is invoked once there is a significant location change, it is also running on a completely different process so you don't really have a UI or access to your application instance.
What you need to do to communicate with your app is firing a local notification or launching an intent or storing the location into a file or a database and once your app is launched get the data from there.
I need some help with Flink Streaming. I have produced a simple Hello-world type of code below. This streams Avro messages from RabbitMQ and persists it to HDFS. I hope someone can review the code, and maybe it can help others.
Most examples I've found for Flink streaming sends results to std-out. I actually wanted to save the data to Hadoop. I read that, in theory, you can stream with Flink to wherever you like. I haven't found any example saving data to HDFS actually. But, based on the examples I did find, and trials and errors, I have come with the below code.
The source of the data, here, is RabbitMQ. I use a client app to send "MyAvroObjects" to RabbitMQ. MyAvroObject.java - not included - is generated from avro IDL... Can be any avro message.
The code below, consumes the RabbitMQ messages, and saves this to HDFS, as avro files... Well, that's what I hope.
package com.johanw.flink.stackoverflow;
import java.io.IOException;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.mapred.AvroKey;
import org.apache.avro.mapred.AvroOutputFormat;
import org.apache.avro.mapred.AvroWrapper;
import org.apache.avro.mapreduce.AvroJob;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.TypeInformation;
import org.apache.flink.api.java.hadoop.mapred.HadoopOutputFormat;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.typeutils.TypeExtractor;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.sink.FileSinkFunctionByMillis;
import org.apache.flink.streaming.connectors.rabbitmq.RMQSource;
import org.apache.flink.streaming.util.serialization.DeserializationSchema;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.Job;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RMQToHadoop {
public class MyDeserializationSchema implements DeserializationSchema<MyAvroObject> {
private static final long serialVersionUID = 1L;
#Override
public TypeInformation<MyAvroObject> getProducedType() {
return TypeExtractor.getForClass(MyAvroObject.class);
}
#Override
public MyAvroObject deserialize(byte[] array) throws IOException {
SpecificDatumReader<MyAvroObject> reader = new SpecificDatumReader<MyAvroObject>(MyAvroObject.getClassSchema());
Decoder decoder = DecoderFactory.get().binaryDecoder(array, null);
MyAvroObject MyAvroObject = reader.read(null, decoder);
return MyAvroObject;
}
#Override
public boolean isEndOfStream(MyAvroObject arg0) {
return false;
}
}
private String hostName;
private String queueName;
public final static String path = "/hdfsroot";
private static Logger logger = LoggerFactory.getLogger(RMQToHadoop.class);
public RMQToHadoop(String hostName, String queueName) {
super();
this.hostName = hostName;
this.queueName = queueName;
}
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
public void run() {
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
logger.info("Running " + RMQToHadoop.class.getName());
DataStream<MyAvroObject> socketStockStream = env.addSource(new RMQSource<>(hostName, queueName, new MyDeserializationSchema()));
Job job;
try {
job = Job.getInstance();
AvroJob.setInputKeySchema(job, MyAvroObject.getClassSchema());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
JobConf jobConf = new JobConf(Job.getInstance().getConfiguration());
jobConf.set("avro.output.schema", MyAvroObject.getClassSchema().toString());
org.apache.avro.mapred.AvroOutputFormat<MyAvroObject> akof = new AvroOutputFormat<MyAvroObject>();
HadoopOutputFormat<AvroWrapper<MyAvroObject>, NullWritable> hof = new HadoopOutputFormat<AvroWrapper<MyAvroObject>, NullWritable>(akof, jobConf);
FileSinkFunctionByMillis<Tuple2<AvroWrapper<MyAvroObject>, NullWritable>> fileSinkFunctionByMillis = new FileSinkFunctionByMillis<Tuple2<AvroWrapper<MyAvroObject>, NullWritable>>(hof, 10000l);
org.apache.hadoop.mapred.FileOutputFormat.setOutputPath(jobConf, new Path(path));
socketStockStream.map(new MapFunction<MyAvroObject, Tuple2<AvroWrapper<MyAvroObject>, NullWritable>>() {
private static final long serialVersionUID = 1L;
#Override
public Tuple2<AvroWrapper<MyAvroObject>, NullWritable> map(MyAvroObject envelope) throws Exception {
logger.info("map");
AvroKey<MyAvroObject> key = new AvroKey<MyAvroObject>(envelope);
Tuple2<AvroWrapper<MyAvroObject>, NullWritable> tupple = new Tuple2<AvroWrapper<MyAvroObject>, NullWritable>(key, NullWritable.get());
return tupple;
}
}).addSink(fileSinkFunctionByMillis);
try {
env.execute();
} catch (Exception e) {
logger.error("Error while running " + RMQToHadoop.class + ".", e);
}
} catch (IOException e) {
logger.error("Error while running " + RMQToHadoop.class + ".", e);
}
}
public static void main(String[] args) throws IOException {
RMQToHadoop toHadoop = new RMQToHadoop("localhost", "rabbitTestQueue");
toHadoop.run();
}
}
If you prefer another source, other than RabbitMQ, then it works fine using another source instead. E.g. using a Kafka consumer:
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer082;
...
DataStreamSource<MyAvroObject> socketStockStream = env.addSource(new FlinkKafkaConsumer082<MyAvroObject>(topic, new MyDeserializationSchema(), sourceProperties));
Questions:
Please review. Is this good practice for saving data to HDFS?
What if the process of streaming is causing an issue, say during serialisation. It generates and exception, and the code just exits. Spark streaming depends on Yarn automatically restarting the app. Is this also good practice when using Flink?
I'm using the FileSinkFunctionByMillis. I was actually hoping to use something like a HdfsSinkFunction, but that doesn't exist. So the FileSinkFunctionByMillis was the closest to this, which made sense to me. Again the documentation that I found lacks any explanation what to do, so I'm only guessing.
When I run this locally, then a I find a directory structure like "C:\hdfsroot_temporary\0_temporary\attempt__0000_r_000001_0", which is... basare. Any ideas here?
By the way, when you want to save the data to Kafka back, I was able to do so using...
Properties destProperties = new Properties();
destProperties.setProperty("bootstrap.servers", bootstrapServers);
FlinkKafkaProducer<MyAvroObject> kafkaProducer = new FlinkKafkaProducer<L3Result>("MyKafkaTopic", new MySerializationSchema(), destProperties);
Many thanks in advance!!!!
I think FileSinkFunctionByMillis can be used but this would mean that your streaming program is not fault-tolerant. Meaning that if your sources or machines or writing fail then your program will crash without being able to recover.
I suggest you look at using the RollingSink (https://ci.apache.org/projects/flink/flink-docs-release-0.10/apis/streaming_guide.html#hadoop-filesystem). This can be used to create Flum-like pipelines to ingest data into HDFS (or other file systems). The rolling sink is a recoverable sink, meaning that your program would be fault-tolerant since the Kafka consumer is also fault-tolerant. Also you can specify a custom Writer to write the data in any format you want, for example Avro.
I want to wake up ejb timer on every two second. For that I am creating ScheulerExpression as the code below...
package com.fks.nclp.ejb.timer.service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.ScheduleExpression;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import com.sun.jersey.spi.resource.Singleton;
#LocalBean
#Singleton
#Startup
public class HelloWorldService {
#Resource
TimerService timerService;
#PostConstruct
public void initialize(){
System.out.println("EJB PRE CONSTRUCT");
ScheduleExpression expression = new ScheduleExpression();
//SET TIMER TO 2 SEC
expression.hour("*");
expression.minute("*");
expression.second("*/2");
timerService.createCalendarTimer(expression,new TimerConfig("TimerScheduler",false));
}
#Timeout
public void startTimer(){
System.out.println("THIS IS EJB TIMER PROGRAM");
}
}
But ... the EJB container is not waking up the scheduler after every two second.
Any Suggestion on this ?
How can I make the expression to wake up every two second.
Thanks,
Gunjan.
There are two things which might be causing problem :
The import statement seems incorrect, which is com.sun.jersey.spi.resource.Singleton, but should be javax.ejb.Singleton.
Try removing #LocalBean annotation.