Кэш-память DDS DataReader разрывается и больше не доступна - PullRequest
1 голос
/ 05 ноября 2010

Работа с библиотекой dds на i386, попытка получить сэмплы несколько раз.Я явно 'read в' не 'take в' образец, поэтому они никогда не должны истекать или быть удалены.

  • Запустите два приложения доски, (1) и (2)
  • Выполните чтение в обоих приложениях.Это вернет сообщение «Кэш пуст».
  • Запись из (1), идентификатор датчика: 1, идентификатор события: 1, значение: 1.
  • Считывание из (1), подтверждение значений
  • Чтение из (2), подтверждение значений
  • Запись из (2), идентификатор датчика: 1, идентификатор события: 1, значение: 2.
  • Чтение из (2), "кеш пуст"
  • Чтение из (1), "кеш пуст"

Кажется, я "сломал" его!Я считаю, что время жизни образцов должно быть бесконечным (или я так понял ... но не могу подтвердить!) - но я не могу установить это явно.topicQos.lifespan.duration относится к типу Duration_t, но я не могу установить для него значение "new Duration_t(Duration_t.DURATION_INFINITY_SEC,Duration_t.DURATION_INFINITY_NSEC)", поскольку оно уже завершено?

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();
  }
}

1 Ответ

1 голос
/ 19 сентября 2011

Проблема, похоже, не связана с lifespan.

Я не уверен, какую реализацию DDS вы используете, но согласно спецификации DDS вы выполняете операцию нулевого копирования вdumpCache метод.Возможно, используемая вами реализация ведет себя так, если вы забудете вернуть кредит.

Обычно вы должны return_loan после чтения / взятия с нулевой копией.

Поэтому, пожалуйста, добавьте следующий код в конце вашего dumpCache метода:

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