1

Opération avec une bibliothèque dds sur i386, en essayant de tirer des échantillons de manière répétée. Je suis explicitement 'read' ne 'take' l'échantillon, donc ils ne devraient jamais expirer ou être supprimés.Le cache DDS DataReader se casse et n'est plus accessible

  • Démarrer deux applications tableau noir, (1) et (2)
  • effectuer une lecture dans les deux applications. Cela retournera "Le cache est vide".
  • Ecrire à partir (1), id capteur: 1, ID d'événement: 1, valeur: 1.
  • Lire à partir (1), confirmer les valeurs
  • Lire à partir (2), confirmer les valeurs
  • Ecrire à partir (2), id capteur: 1, ID d'événement: 1, valeur: 2.
  • Lire à partir (2), "cache est vide"
  • Lire à partir (1), "cache est vide"

Il semble que je l'ai "cassé"! Je crois que la durée de vie des échantillons devrait être inifinity (ou si j'ai fini par comprendre ... mais je ne peux pas confirmer!) - mais je ne peux pas le définir explicitement. topicQos.lifespan.duration est du type Duration_t, mais je ne peux pas le définir sur un "nouveau Duration_t(Duration_t.DURATION_INFINITY_SEC,Duration_t.DURATION_INFINITY_NSEC)" car il est déjà finalisé?

public class Main { 

    private static final String EVENT_TOPIC_NAME = "EVENTS"; 
    private static BufferedReader in = null; 
    private static PrintStream out = null; 
    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws IOException { 
    in = new BufferedReader(new InputStreamReader(System.in)); 
    out = new PrintStream(new BufferedOutputStream(System.out)); 

    DomainParticipantFactory factory = DomainParticipantFactory.TheParticipantFactory; 
    DomainParticipant participant = factory.create_participant(100, 
      DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT, 
      null, 
      StatusKind.STATUS_MASK_NONE); 

    EventTypeSupport.register_type(participant, EventTypeSupport.get_type_name()); 

    TopicQos topicQos = new TopicQos(); 
    topicQos.durability.direct_communication = true; 
    topicQos.durability.kind = DurabilityQosPolicyKind.TRANSIENT_DURABILITY_QOS; 
    topicQos.reliability.kind = ReliabilityQosPolicyKind.RELIABLE_RELIABILITY_QOS; 
    topicQos.resource_limits.max_instances = 100; 
    topicQos.resource_limits.max_samples = 100; 
    topicQos.resource_limits.max_samples_per_instance = 1; 
    topicQos.ownership.kind = OwnershipQosPolicyKind.SHARED_OWNERSHIP_QOS; 
    topicQos.history.kind = HistoryQosPolicyKind.KEEP_LAST_HISTORY_QOS; 
    topicQos.history.depth = 1; 
    topicQos.history.refilter = RefilterQosPolicyKind.ALL_REFILTER_QOS; 
    // Since this is on the same computer, and being typed by a human, we can exepct source timestamps to be useful in ordering 
    topicQos.destination_order.kind = DestinationOrderQosPolicyKind.BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS; 

    Topic topic = 
      participant.create_topic(EVENT_TOPIC_NAME, 
      EventTypeSupport.get_type_name(), 
      topicQos, 
      new EventTopicListener(), 
      StatusKind.STATUS_MASK_ALL); 
    exitIfNullBecause(topic, "Could not create topic"); 

    Subscriber subscriber = participant.create_subscriber(DomainParticipant.SUBSCRIBER_QOS_DEFAULT, 
      null, 
      StatusKind.STATUS_MASK_NONE); 
    exitIfNullBecause(subscriber, "Could not create subscriber"); 

    DataReader reader = subscriber.create_datareader(participant.lookup_topicdescription(EVENT_TOPIC_NAME), 
      subscriber.DATAREADER_QOS_USE_TOPIC_QOS, 
      null, 
      StatusKind.STATUS_MASK_NONE); 
    exitIfNullBecause(reader, "Could not create reader"); 
    EventDataReader eventReader = (EventDataReader) reader; 

    Publisher publisher = participant.create_publisher(DomainParticipant.PUBLISHER_QOS_DEFAULT, 
      null, 
      StatusKind.STATUS_MASK_NONE); 
    exitIfNullBecause(publisher, "Could not create publisher"); 

    DataWriter writer = publisher.create_datawriter(topic, 
      publisher.DATAWRITER_QOS_USE_TOPIC_QOS, 
      null, 
      StatusKind.STATUS_MASK_NONE); 
    exitIfNullBecause(writer, "Could not create writer"); 
    EventDataWriter eventWriter = (EventDataWriter)writer; 

    boolean loop = true; 
    byte inputBuffer[] = new byte[1024]; 
    String command; 
    while(loop){ 
     print("Enter action [read|write|exit]: "); 

     command = in.readLine(); 
     if(command.startsWith("r")){ 
     dumpCache(eventReader); 
     } else if(command.startsWith("w")) { 
     writeCache(eventWriter); 
     } else if(command.startsWith("e")){ 
     println("exiting..."); 
     System.exit(0); 
     } else { 
     println("Unknown: '" + command + "'"); 
     } 
    } 

    System.exit(0); 
    } 

    private static void print(String output){ 
    out.print(output); 
    out.flush(); 
    } 
    private static void println(String output){ 
    out.println(output); 
    out.flush(); 
    } 

    private static void exitIfNullBecause(Object thing, String string) { 
    if (thing == null) { 
     println("ERROR: " + string); 
     System.exit(1); 
    } 
    } 
    private static void dumpCache(EventDataReader eventReader) { 
    // Something interesting here: I can creat it with a collection as a paramter. TODO: Investigate! 
    EventSeq eventSeq = new EventSeq(); 
    SampleInfoSeq infoSeq = new SampleInfoSeq(); 

    Event event = null; 
    SampleInfo info = null; 

    try{ 
     eventReader.read(eventSeq, infoSeq, 100, SampleStateKind.ANY_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE); 
    } catch (Exception e){ 
     println("Cache is empty"); 
     return; 
    } 

    Iterator<SampleInfo> infoIter = infoSeq.iterator(); 
    out.printf("| Sensor ID | Event ID | Value |\n"); 
    for(int i=0; i<infoSeq.size(); i++){ 
     event = (Event)eventSeq.get(i); 
     out.printf("| %9d | %8d | %5d |\n", event.sensor_id, event.event_id, event.value); 
    } 
    out.flush(); 
    } 

    private static void writeCache(EventDataWriter eventWriter) throws IOException { 
    Event event = new Event(); 

    print("Sensor ID: "); 
    String sensor_id_str = in.readLine(); 
    print("Event ID: "); 
    String event_id_str = in.readLine(); 
    print("Value: "); 
    String value_str = in.readLine(); 

    Event sample = new Event(); 
    sample.sensor_id = Integer.parseInt(sensor_id_str); 
    sample.event_id = Integer.parseInt(event_id_str); 
    sample.value = Integer.parseInt(value_str); 

    InstanceHandle_t handle = eventWriter.register_instance(sample); 
// eventWriter.write(sample, handle); 
    eventWriter.write_w_timestamp(sample, handle, Time_t.now()); 


    out.printf("SensorID: %s, EventID: %s, Value: %s\n",sensor_id_str,event_id_str,value_str); out.flush(); 
    } 
} 

Répondre

1

Le problème ne semble pas être lié à lifespan. Je ne suis pas sûr de l'implémentation DDS que vous utilisez mais selon la spécification DDS, vous effectuez une opération de copie zéro dans votre méthode dumpCache. Peut-être que la mise en œuvre que vous utilisez se comporte comme ceci si vous oubliez de retourner le prêt.

Vous devriez normalement return_loan après une lecture/prise avec zéro copie.

Alors s'il vous plaît ajoutez le code suivant à la fin de votre méthode dumpCache:

try{ 
    eventReader.return_loan(eventSeq, infoSeq); 
} catch (Exception e){ 
    println("Error returning loan"); 
    return; 
}