1

I was able to cast the cache listener's afterCreate event value to the PdxInstance data type when the region was updated through Geode's REST API. The code below ran fine without any issues. However when I tried updating the region through the custom defined pdx serialization using the Order.hpp and Order.cpp example code that Geode provided, the dynamic cast in my defined cache listener below returned a value with memory address 0x0 and so when it tries to access the fields in the order object, it's giving me segmentation fault. The objectSize() method also returned 0 bytes which suggests to me that the pdx serialisation was not done correctly.

Would someone be able to advise me what I've done incorrectly below?

#include <iostream>
#include <sstream>
#include <string>

#include <geode/CacheFactory.hpp>
#include <geode/PoolManager.hpp>
#include <geode/RegionFactory.hpp>
#include <geode/RegionShortcut.hpp>
#include <geode/TypeRegistry.hpp>
#include <geode/AttributesMutator.hpp>
#include <geode/CacheListener.hpp>
#include <geode/EntryEvent.hpp>
#include <geode/CacheableString.hpp>
#include <geode/PdxInstance.hpp>


#include "Order.hpp"

using namespace apache::geode::client;
using namespace customserializable;


class MyEventHandler : public CacheListener
{
public:
  void afterCreate(const EntryEvent& event) override
  {
    auto key(dynamic_cast<CacheableString *>(event.getKey().get()));

    std::cout << "afterCreate: " << key->value() << std::endl;

    auto mypdx = event.getNewValue().get();

    mypdx->toString();

    mypdx->objectSize();

    PdxInstance *pdx = dynamic_cast<PdxInstance *>(mypdx);

    // auto pdx(dynamic_cast<PdxInstance *>(mypdx));

    int order_id = pdx->getByteField("order_id");
    
    int quantity = pdx->getByteField("quantity");

    std::string name = pdx->getStringField("name");

    std::cout << "Testing" << std::endl;
  }
};

auto MyListener = std::make_shared<MyEventHandler>();

int main(int argc, char** argv) {
  auto cache = CacheFactory()
      .set("log-level", "none")
      .setPdxReadSerialized(true)
      .create();

  cache.getPoolManager()
      .createFactory()
      .addLocator("localhost", 10334)
      .setSubscriptionEnabled(true)
      .create("pool");


  auto regionFactory = cache.createRegionFactory(RegionShortcut::CACHING_PROXY);
  auto region = regionFactory.setPoolName("pool").create("custom_orders");

  cache.getTypeRegistry().registerPdxType(Order::createDeserializable);
  
  region->getAttributesMutator()->setCacheListener(MyListener);

  std::cout << "Create orders" << std::endl;
  auto order1 = std::make_shared<Order>(1, "product x", 23);
  auto order2 = std::make_shared<Order>(2, "product y", 37);

  region->registerAllKeys();

  region->put("Order19" , order1);

  cache.close();
}



Wai Lun Poon
  • 35
  • 1
  • 5

2 Answers2

2

To be clear, what we believe you need here is dynamic_cast<Order*>(mypdx);. Let us know how things turn out!

  • Thank you, I was able to get the order_id and quantity attributes from order with getOrderId() and getQuantity() defined in Order.hpp after changing the cast to Order. This works fine when the custom_order region is updated from within the same client where the cache listener is implemented however when I try to update the custom_order region through a different client (the client has the same code as above but with the cache listener code commented out), it is giving me segmentation faults when it tries to call getOrderId(). Would you be able to advise me where the issue is? – Wai Lun Poon Sep 19 '21 at 20:46
1

Geode client developer here,

Order derives from PdxSerializable, not PdxInstance. If you look at their inheritance hierarchies, you'll see they're siblings to one another, not one being the descendant of the other. Dynamic casts are, among other things, also a kind of runtime type query, so you're effectively asking if mypdx derives from PdxInstance, and returning a nullptr is the result indicating false, which is correct. Change the type in your cast, and I think you'll have much more satisfying results.

Good luck, and keep asking questions, we do try to pay attention and respond.