buzz-lang / BittyBuzz

BittyBuzz is an implementation of Buzz for microcrontrollers.
MIT License
8 stars 7 forks source link

Buzz stigmergy messages resent when lamport are equal. #13

Closed xgroleau closed 3 years ago

xgroleau commented 3 years ago

I'm not 100% sure of the problem here, but when I have two robots and one puts in the stigmergy every 10 sec, eventually the message goes back and forth between the two robots without stopping. Eating our CPU and bandwidth.

It's seems the function bbzlamport_isnewer return true if the lamport are equal, causing the same message to be resent over and over again since it assumes it's true. Here is the line where it's called and here is the definition of the function.

When the msg->vs.lamport = 1 and data->timestamp =1, the function returns true, causing the message to be resent while it should do nothing.

Again I'm not sure if this is the only cause, maybe I misdiagnosed or maybe there are some problem in my code too, I will continue to debug and update here.

Here is my buzz code if it can be of any use

function init() {
  counter = 0;
  stig = stigmergy.create(1);
  if(id == 1){
    stig.put("leader", 1);
  }
}

# runs every 100ms
function step() { 
  if(counter == 100 and id == 1) {
    var data = stig.get("leader");
    log("Current data in stig: ", data, " size: ", stig.size());
    counter = 0;
  }
  counter = counter + 1;
}
xgroleau commented 3 years ago

I've temporarily disable updating a propagating if the lamports are equals and it does seem to help a lot and reduce the number of message to a manageable level, but it still seems to be a lot more of message sent that it's supposed to, I'll continue to investigate.

beltrame commented 3 years ago

When lamport clocks are equal, the vm should call the conflict resolution function (as in the original Buzz). @AnthonyD973 and @Belkharym, do you remember if it is the case here? It might be that the default conflict resolution is incorrect

xgroleau commented 3 years ago

After some searching, it seems the circular buffer skips a field for the outputs messages when appending to the cbuff. On the second call of bbzoutmsg_queue_append_vstig (caused by the get in the script) it seems to skip a field in the buffer, it writes at index 2 instead of at index 1. So when I try to get the next data in the cbuf, an uninitialized (at index 1) bbzmsg_t is obtained (since it was written at index 2).

In other words, the code does

vm->outmsg.buf[0] = vstig query msg; vm->outmsg.buf[2] = vstig query msg;

While it should do vm->outmsg.buf[0] = vstig query msg; vm->outmsg.buf[1] = vstig query msg;

And since the vm->outmsg.buf[1] message is not initialized, it's a broadcast message with invalid values.