How to consume only the latest message published from the topic and ignore all previously published message in Pulsar - apache-pulsar

Lets say i have a publisher app and it runs and publishes 20 messages and then goes down
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
public class TestPub {
public static void main(String[] args) throws PulsarClientException, InterruptedException {
PulsarClient client = PulsarClient.builder()
.serviceUrl("pulsar://172.20.170.147:6650")
.build();
Producer<byte[]> producer = client.newProducer()
.topic("example-topic")
.create();
for (int i = 0; i < 20; i++)
{
String msg = ""+i;
producer.newMessage()
.value(msg.getBytes())
.send();
System.out.println("Sent:"+msg);
Thread.sleep(1000);
}
}
}
and then i have a subscriber app which can use either a consumer or reader but it starts after the publisher is done, i need it to read only the latest message published by publisher before i thought this code should do it but somehow it is not working, any clues folks?
import org.apache.pulsar.client.api.*;
public class TestSub {
public static void main(String[] args) throws PulsarClientException {
PulsarClient client = PulsarClient.builder()
.serviceUrl("pulsar://172.20.170.147:6650")
.build();
read(client);
consume(client);
}
static void consume(PulsarClient client) throws PulsarClientException {
Consumer consumer = client.newConsumer()
.topic("example-topic")
.subscriptionName("my-subscription-consumer")
.subscriptionType(SubscriptionType.Exclusive)
.subscriptionInitialPosition(SubscriptionInitialPosition.Latest)
.startMessageIdInclusive()
.subscribe();
//consumer.seek(MessageId.latest);
while (true) {
// Wait for a message
Message msg = consumer.receive();
try {
System.out.println("Message consumed: " +
new String(msg.getData()));
//consumer.acknowledge(msg);
} catch (Exception e) {
consumer.negativeAcknowledge(msg);
}
}
}
static void read(PulsarClient client) throws PulsarClientException {
Reader consumer = client.newReader()
.topic("example-topic")
.subscriptionName("my-subscription-reader")
.startMessageIdInclusive()
.startMessageId(MessageId.latest)
.create()
;
while (true) {
// Wait for a message
Message msg = consumer.readNext();
try {
System.out.println("Message read: " +
new String(msg.getData()));
//consumer.acknowledge(msg);
} catch (Exception e) {
System.out.println(e);
}
}
}
}

Based on the Pulsar API, Message.latest is "MessageId that represents the next message published in the topic." It is NOT the last message published to the topic, but rather the next one to be published. I can see where the naming of this enum could cause that confusion.
So in this scenario the expected behavior is for the readers/consumers to wait until another message is published to the topic before they are triggered to run.

Related

Using Multiple threads to access a Single Jedis client

I am trying to access a jedis client with multiple threads where one thread can simple read and write to the database while the other thread can subscribe and a listen to a channel . Is this possible in jedis . Or if it is possible to write variables to one client by any other client that would also work.
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
public class Testing1 {
public static void main(String args[])
{
final Jedis jedis = new Jedis("localhost");
Runnable runnable =()->
{
System.out.println(jedis.clientId());
jedis.set("acd","acg");
String str=jedis.get("acd");
System.out.println(str);
};
Runnable runnable2 =()->
{
System.out.println(jedis.clientId());
JedisPubSub jedisPubSub = new JedisPubSub()
{
#Override
public void onMessage(String channel, String message) {
System.out.println("Channel " + channel + " has sent a message : " + message );
if(channel.equals("C1")) {
/* Unsubscribe from channel C1 after first message is received. */
unsubscribe(channel);
}
}
#Override
public void onSubscribe(String channel, int subscribedChannels) {
System.out.println("Client is Subscribed to channel : "+ channel);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
}
#Override
public void onUnsubscribe(String channel, int subscribedChannels) {
System.out.println("Client is Unsubscribed from channel : "+ channel);
System.out.println("Client is Subscribed to "+ subscribedChannels + " no. of channels");
}
};
jedis.subscribe(jedisPubSub, "__redis__:invalidate");
};
/ Thread thread= new Thread(runnable);
Thread thread1= new Thread(runnable2);
thread.start();
thread1.start();
jedis.set("harry","veer");
System.out.println(jedis.get("harry"));
}
}
Here is what I am trying basically please help me with this

Sending message to IoTHub fails

I have been working on a device which is sending some data to an Azure IoT hub
The device is doing this on two different locations in the code. On one side it works perfectly and I can connect to the Hub via Connection String and transport type MQTT_WebSocket_Only.
public static class Mqtt2IoTNew
{
private static string _DeviceConnectionString = Properties.Settings.Default.MqttUri;
private static TransportType _TransportType = TransportType.Mqtt_WebSocket_Only;
public static void Send(object argEntry, bool argIsList)
{
var deviceClient = DeviceClient.CreateFromConnectionString(_DeviceConnectionString, _TransportType);
deviceClient.ReceiveAsync(TimeSpan.FromSeconds(2)).Wait();
var message = new Message(deviceClient, argEntry, argIsList);
message.RunAsync().GetAwaiter().GetResult();
}
}
internal class Message
{
private DeviceClient _DeviceClient;
private readonly string _Message;
public Message(DeviceClient argDeviceClient, object argEntry, bool isList)
{
_DeviceClient = argDeviceClient;
StringBuilder stb = new StringBuilder();
if (isList)
{
foreach (var entity in (List<object>) argEntry)
{
stb.Append("<entity>").Append(JsonConvert.SerializeObject(entity)).Append("</entity>\n");
}
}
else
{
stb.Append(JsonConvert.SerializeObject(argEntry));
}
_Message = stb.ToString();
}
public async Task RunAsync()
{
await SendEvent().ConfigureAwait(false);
}
private async Task SendEvent()
{
Microsoft.Azure.Devices.Client.Message eventMessage = new Microsoft.Azure.Devices.Client.Message(Encoding.UTF8.GetBytes(_Message));
await _DeviceClient.SendEventAsync(eventMessage).ConfigureAwait(false);
}
}
//Call of method that does not work
protected override void DoOnCompleted(IRepository argRepository)
{
if (_CurrentlySendingTreadId.HasValue)
{
if (_CurrentlySendingTreadId.Value == Thread.CurrentThread.ManagedThreadId)
{
return;
}
}
TaskFactoryProvider.GetFactory().StartNew(()=>SendBatchProtocols());
}
public bool SendBatchProtocols()
{
using (var repository = RepositoryProviderHolder.RepositoryProvider.GetRepository(Constants.CONTAINERCONTRACT_PRODUCTIONREPOSITORY))
{
IQueryable<BatchProtocol> batchProtocolQuery = repository.GetQuery<BatchProtocol>().OrderBy(bp => bp.InternalNoInteger);
batchProtocolQuery = batchProtocolQuery.Where(bp => !bp.IsArchived).Take(1);
if (!batchProtocolQuery.Any()) return false;
var batchProtocols = batchProtocolQuery.ToList();
IsBatchProtocolSend = false;
try
{
foreach (var bps in batchProtocols)
{
Mqtt2IoTNew.Send(bps,false);
}
IsBatchProtocolSend = true;
}
catch (Exception ex)
{
throw;
}
}
return IsBatchProtocolSend;
}
//Call of Method that does work
private void AddEntitiesAndSaveChanges(IEnumerable argEntities)
{
if (argEntities == null)
{
return;
}
lock (_UnderlyingRepositoryAccessLockObject)
{
#region Log2DornerIoT
if (Properties.Settings.Default.Log2DornerIoT)
{
List<object> entities = new List<object>();
int i = 0;
foreach (var entity in argEntities)
{
if (i < 100)
{
entities.Add(entity);
i++;
}
else
{
try
{
Mqtt2IoTNew.Send(entities, true);
}
catch (Exception e)
{
throw;
}
entities.Clear();
i = 0;
}
}
}
}
on the other part of the code, I am only colling the same class to use to send method in the same way but here I get an exception which says "TLS authentication error" and the inner exception "Unable to connect to the remote server", "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel".
But: I never used any kind of authorization not in the first part which works perfectly neither in the second.
I would be very happy if someone could help me. I have found nothing so fare regarding this issue.
Thanks for your time.
Michael
I found the reason why it didn't work. There was a Persmissice Certificate Policy applied that blocked the certificate at one side of the project. I disabled it and now it works perfectly fine.
Thanks for the help anyway.

Trouble Writing multiThread Chat program

im writing a multithread chat program where i hope to have a server connected to multiple clients, the clients can talk to each and send messages to each other. I want all messages from the clients to be visible to the server, moreover that the server can send messages to all visible clients. My program only connects the server to one client and they can send messages.
package chatserver2;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
// import all the class that you will need for functionailty
// extends jframe to develop gui's in java
public class Server2 {
private static JTextField userInput; //
private static JTextArea theChatWindow; //
private static ObjectOutputStream output; // stream data out
private static ObjectInputStream input; // stream data in
private static ServerSocket server;
private static Socket connection; // socket means set up connetion between 2 computers
private static JFrame frame;
private static int n;
//Constructor
public static void main(String[] args) throws IOException {
Server2 obj = new Server2();
// Socket sock=new Socket("localhost",6789);
System.out.println("Hello 4");
obj.RunServer();
System.out.println("Hello 3");
try {
while (true) {
System.out.println("Hello 2");
Handler obj2 = new Handler();
//Handler obj3=new Handler();
obj2.start();
System.out.println("Accepted connection from "
+ connection.getInetAddress() + " at port "
+ connection.getPort());
n++;
System.out.println("Count " + n);
}
} finally {
connection.close();
}
}
public Server2() {
frame = new JFrame();
userInput = new JTextField();
userInput.setEditable(false); // set this false so you dont send messages when noone is available to chat
// action event listener to check when the user hits enter for example
userInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
sendMessage(event.getActionCommand()); // string entered in the textfield
userInput.setText(""); // reset text area to blank again
}
}
);
// create the chat window
frame.add(userInput, BorderLayout.NORTH);
theChatWindow = new JTextArea();
frame.add(new JScrollPane(theChatWindow));
frame.setSize(300, 150);
frame.setVisible(true);
}
// run the server after gui created
public void RunServer() {
try {
server = new ServerSocket(6789); // 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {
try {
waitForConnection(); // wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {
showMessage("\n Server ended Connection");
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
//Wait for a connection then display connection information
private void waitForConnection() {
showMessage("waiting for someone to connect to chat room....\n");
try {
connection = server.accept();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
showMessage("Now connected to" + connection.getInetAddress().getHostName());
showMessage(" at port " + connection.getPort());
}
// stream function to send and recive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
// String message = "WAIT";
// sendMessage(message);
//showMessage("\n Connection streams are now setup \n");
}
// this code while run during chat conversions
private void whileChatting() throws IOException {
String message = "WAIT ";
sendMessage(message);
allowTyping(true); // allow user to type when connection
do {
// have conversion while the client does not type end
try {
message = (String) input.readObject(); // stores input object message in a string variable
showMessage("\n " + message);
System.out.println("Message from Client " + message);
} catch (ClassNotFoundException classnotfoundException) {
showMessage("\n i dont not what the user has sent");
}
} while (!message.equals("CLIENT - END"));// if user types end program stops
}
private void closeChat() {
showMessage("\n closing connections...\n");
allowTyping(true);
try {
output.close(); // close output stream
input.close(); // close input stream
connection.close(); // close the main socket connection
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// send message to the client
private void sendMessage(String message) {
try {
output.writeObject(message);
output.flush(); // send all data out
showMessage("\nServer - " + message);
System.out.println("Message to client " + message);
} catch (IOException ioexception) {
theChatWindow.append("\n ERROR: Message cant send");
}
}
// update the chat window (GUI)
private void showMessage(final String text) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
theChatWindow.append(text);
}
}
);
}
// let the user type messages in their chat window
private void allowTyping(final boolean trueOrFalse) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
userInput.setEditable(trueOrFalse);
}
}
);
}
public static class Handler extends Thread {
private Socket connection;
// static private ServerSocket server;
public Handler() {
// this.socket = socket;
String message = "WAIT";
}
//connection = server.accept();
public void run() {
System.out.println("Connect" + Server2.connection);
while (true) {
try {
waitForConnection();
setupStreams();
whileChatting();
} catch (IOException ex) {
Logger.getLogger(Server2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void waitForConnection() {
System.out.println("Heelo");
showMessage("waiting for someone to connect to chat room....\n");
System.out.println("server" + server);
try {
connection = server.accept();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
System.out.println("Connection" + connection);
showMessage("Now connected to" + connection.getInetAddress().getHostName());
showMessage("AT port" + connection.getPort());
}
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
showMessage("\n Connection streams are now setup \n");
}
// this code while run during chat conversions
private void whileChatting() throws IOException {
String message = " You are now connected ";
sendMessage(message);
allowTyping(true); // allow user to type when connection
do {
// have conversion while the client does not type end
try {
message = (String) input.readObject(); // stores input object message in a string variable
showMessage("\n " + message);
} catch (ClassNotFoundException classnotfoundException) {
showMessage("\n i dont not what the user has sent");
}
} while (!message.equals("CLIENT - END"));// if user types end program stops
}
private void closeChat() {
showMessage("\n closing connections...\n");
allowTyping(true);
try {
output.close(); // close output stream
input.close(); // close input stream
connection.close(); // close the main socket connection
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// send message to the client
static private void sendMessage(String message) {
try {
output.writeObject(message);
output.flush(); // send all data out
showMessage("\nServer - " + message);
} catch (IOException ioexception) {
theChatWindow.append("\n ERROR: Message cant send");
}
}
// update the chat window (GUI)
static private void showMessage(final String text) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
theChatWindow.append(text);
}
}
);
}
// let the user type messages in their chat window
private void allowTyping(final boolean trueOrFalse) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
userInput.setEditable(trueOrFalse);
}
}
);
}
}
}
Here is the client :
package chatserver2;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// import all the class that you will need for functionailty
// extends jframe to develop gui's in java
public class Client2 extends JFrame {
private JTextField userInput; //
private JTextArea theChatWindow; //
private ObjectOutputStream output; // stream data out
private ObjectInputStream input; // stream data in
private Socket connection; // socket means set up connetion between 2 computers
//Constructor
public Client2() {
super("My Chat Service");
userInput = new JTextField();
userInput.setEditable(false); // set this false so you dont send messages when noone is available to chat
// action event listener to check when the user hits enter for example
userInput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
sendMessage(event.getActionCommand()); // string entered in the textfield
userInput.setText(""); // reset text area to blank again
}
}
);
// create the chat window
add(userInput, BorderLayout.NORTH);
theChatWindow = new JTextArea();
add(new JScrollPane(theChatWindow));
setSize(300, 150);
setVisible(true);
}
// run the server after gui created
public void RunServer() {
try {
connection = new Socket("localhost", 6789);// 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {
try {
// wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {
showMessage("\n Server ended Connection");
} finally {
closeChat();
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
//Wait for a connection then display connection information
// stream function to send and recive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
showMessage("\n Connection streams are now setup \n");
}
// this code while run during chat conversions
private void whileChatting() throws IOException {
String message = "";
allowTyping(true); // allow user to type when connection
do {
// have conversion while the client does not type end
try {
message = (String) input.readObject(); // stores input object message in a string variable
System.out.println("message " + message);
if (message.equals("WAIT")) {
ServerSocket server2 = new ServerSocket(5000);
System.out.println("Hello");
message = "5000";
sendMessage(message);
}
System.out.println("From server " + message);
showMessage("\n " + message);
} catch (ClassNotFoundException classnotfoundException) {
showMessage("\n i dont not what the user has sent");
}
} while (!message.equals("CLIENT - END"));// if user types end program stops
}
private void closeChat() {
showMessage("\n closing connections...\n");
allowTyping(true);
try {
output.close(); // close output stream
input.close(); // close input stream
connection.close(); // close the main socket connection
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// send message to the client
private void sendMessage(String message) {
try {
output.writeObject(" - " + message);
output.flush(); // send all data out
showMessage("\nServer - " + message);
} catch (IOException ioexception) {
theChatWindow.append("\n ERROR: Message cant send");
}
}
// update the chat window (GUI)
private void showMessage(final String text) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
theChatWindow.append(text);
}
}
);
}
// let the user type messages in their chat window
private void allowTyping(final boolean trueOrFalse) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
userInput.setEditable(trueOrFalse);
}
}
);
}
public static void main(String[] args) {
Client2 obj = new Client2();
obj.RunServer();
}
}

When the ProcessEventsAsync(PartitionContext context, ienumerable<EventData> messages) method will be fired

I am currently working on Internet Of Things, in my current project I was Created the One Azure Cloud Service Project in that I Created the Worker Role, inside the worker role i have wrote below lines of code.
public class WorkerRole : RoleEntryPoint
{
private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
private static string connectionString;
private static string eventHubName;
public static ServiceClient iotHubServiceClient { get; private set; }
public static EventHubClient eventHubClient { get; private set; }
public override void Run()
{
Trace.TraceInformation("EventsForwarding Run()...\n");
try
{
this.RunAsync(this.cancellationTokenSource.Token).Wait();
}
finally
{
this.runCompleteEvent.Set();
}
}
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
bool result = base.OnStart();
Trace.TraceInformation("EventsForwarding OnStart()...\n");
connectionString = ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"];
eventHubName = ConfigurationManager.AppSettings["Microsoft.ServiceBus.EventHubName"];
string storageAccountName = ConfigurationManager.AppSettings["AzureStorage.AccountName"];
string storageAccountKey = ConfigurationManager.AppSettings["AzureStorage.Key"];
string storageAccountString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
storageAccountName, storageAccountKey);
string iotHubConnectionString = ConfigurationManager.AppSettings["AzureIoTHub.ConnectionString"];
iotHubServiceClient = ServiceClient.CreateFromConnectionString(iotHubConnectionString);
eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
var defaultConsumerGroup = eventHubClient.GetDefaultConsumerGroup();
string eventProcessorHostName = "SensorEventProcessor";
EventProcessorHost eventProcessorHost = new EventProcessorHost(eventProcessorHostName, eventHubName, defaultConsumerGroup.GroupName, connectionString, storageAccountString);
eventProcessorHost.RegisterEventProcessorAsync<SensorEventProcessor>().Wait();
Trace.TraceInformation("Receiving events...\n");
return result;
}
public override void OnStop()
{
Trace.TraceInformation("EventsForwarding is OnStop()...");
this.cancellationTokenSource.Cancel();
this.runCompleteEvent.WaitOne();
base.OnStop();
Trace.TraceInformation("EventsForwarding has stopped");
}
private async Task RunAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
//Trace.TraceInformation("EventsToCommmandsService running...\n");
await Task.Delay(1000);
}
}
}
Next I have wrote the below lines of code in SensorEventProcessor, for receiving the messages from event hub and send those messages to IoT hub.
class SensorEventProcessor : IEventProcessor
{
Stopwatch checkpointStopWatch;
PartitionContext partitionContext;
public async Task CloseAsync(PartitionContext context, CloseReason reason)
{
Trace.TraceInformation(string.Format("EventProcessor Shuting Down. Partition '{0}', Reason: '{1}'.", this.partitionContext.Lease.PartitionId, reason.ToString()));
if (reason == CloseReason.Shutdown)
{
await context.CheckpointAsync();
}
}
public Task OpenAsync(PartitionContext context)
{
Trace.TraceInformation(string.Format("Initializing EventProcessor: Partition: '{0}', Offset: '{1}'", context.Lease.PartitionId, context.Lease.Offset));
this.partitionContext = context;
this.checkpointStopWatch = new Stopwatch();
this.checkpointStopWatch.Start();
return Task.FromResult<object>(null);
}
public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
Trace.TraceInformation("\n");
Trace.TraceInformation("........ProcessEventsAsync........");
//string commandParameterNew = "{\"Name\":\"AlarmThreshold\",\"Parameters\":{\"SensorId\":\"" + "Hello World" + "\"}}";
//await WorkerRole.iotHubServiceClient.SendAsync("astranidevice", new Microsoft.Azure.Devices.Message(Encoding.UTF8.GetBytes(commandParameterNew)));
foreach (EventData eventData in messages)
{
try
{
string jsonString = Encoding.UTF8.GetString(eventData.GetBytes());
Trace.TraceInformation(string.Format("Message received at '{0}'. Partition: '{1}'",
eventData.EnqueuedTimeUtc.ToLocalTime(), this.partitionContext.Lease.PartitionId));
Trace.TraceInformation(string.Format("-->Raw Data: '{0}'", jsonString));
SimpleTemperatureAlertData newSensorEvent = this.DeserializeEventData(jsonString);
Trace.TraceInformation(string.Format("-->Serialized Data: '{0}', '{1}', '{2}', '{3}', '{4}'",
newSensorEvent.Time, newSensorEvent.RoomTemp, newSensorEvent.RoomPressure, newSensorEvent.RoomAlt, newSensorEvent.DeviceId));
// Issuing alarm to device.
string commandParameterNew = "{\"Name\":\"AlarmThreshold\",\"Parameters\":{\"SensorId\":\"" + "Hello World" + "\"}}";
Trace.TraceInformation("Issuing alarm to device: '{0}', from sensor: '{1}'", newSensorEvent.DeviceId, newSensorEvent.RoomTemp);
Trace.TraceInformation("New Command Parameter: '{0}'", commandParameterNew);
await WorkerRole.iotHubServiceClient.SendAsync(newSensorEvent.DeviceId, new Microsoft.Azure.Devices.Message(Encoding.UTF8.GetBytes(commandParameterNew)));
}
catch (Exception ex)
{
Trace.TraceInformation("Error in ProssEventsAsync -- {0}\n", ex.Message);
}
}
await context.CheckpointAsync();
}
private SimpleTemperatureAlertData DeserializeEventData(string eventDataString)
{
return JsonConvert.DeserializeObject<SimpleTemperatureAlertData>(eventDataString);
}
}
When I was debug my code, the ProcessEventsAsync(PartitionContext context, IEnumerable messages) method will never call and just enter into OpenAsync() method then itstop the debugging.
Please tell me Where I did mistake in my project and tell me when the ProcessEventsAsync() method will call.
Regards,
Pradeep
IEventProcessor.ProcessEventsAsync is invoked when there are any unprocessed messages in the EventHub.
An Event Hub contains multiple partitions. A partition is an ordered sequence of events. Within a partition, each event includes an offset. This offset is used by consumers (IEventProcessor) to show the location in the event sequence for a given partition. When an IEventProcessor connects (EventProcessorHost.RegisterEventProcessorAsync), it passes this offset to the Event Hub to specify the location at which to start reading. When there are unprocessed messages (events with higher offset), they are delivered to the IEventProcessor. Checkpointing is used to persist the offset of processed messages (PartitionContext.CheckpointAsync).
You can find detailed information about the internals of EventHub: Azure Event Hubs overview
Have you sent any messages to the EventHub (EventHubClient.SendAsync(EventData))?

Thread consuming queue, Terminate

I would like to know if the following method is correct or not.
I've producer and consumer thread that work on a common BlockingQueue.
The producer is a sniffer thread so it will stop automatically,but fot the consumer i think to terminate with a loop on status (alive/dead) of producer thread. Any suggestions? Thanks
-)From the Main thread:
ArrayBlockingQueue<PcapPacket> queue = new ArrayBlockingQueue<>();
Producer p = new Producer(queue);
Thread t1 =new Thread(p);
t1.start();
Consumer c = new Consumer(queue,t1);
new Thread(c).start();
-)Producer
public void run() {
public void nextPacket(PcapPacket packet, String user) {
try {
queue.put(packet);
} catch (InterruptedException ex) {
}
-) Consumer
public void run() {
while(producer.isAlive()){
try {
//Thread.sleep(50);
packet=queue.take();
Polling producer's status is sub-optimal.
Preferred approach is to make producer, during producer exit, put some 'poison pill' into queue, and for consumer to end it's loop as soon as it have received that pill:
class Producer implements Runnable {
static final Object TIME_TO_STOP = new Object();
private final BlockingQueue<Object> q;
Producer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
try {
while (true) {
q.put(readNextPacket());
}
} finally {
// exception happened
try {
q.put(TIME_TO_STOP);
} catch (InterruptedException e) {
// somehow log failure to stop properly
}
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Object> q;
Consumer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
while (true) {
Object packet = q.take();
if (packet == Producer.TIME_TO_STOP) {
break;
}
// process packet
}
}
}

Resources