php memcached set function lock -


i use php memcached implement token code below:

    function addtokenkey($token)     {        $alltokens = $this->memcache->get("alltokens");           if(gettype($alltokens) == "boolean")         {             $array = array();             array_push($array,$token);              $this->memcache->set("alltokens",$array);              echo "addtokenkey 1.2:".count($array)."<br>";         }         else{                             echo "addtokenkey 2.1:".count($alltokens)."<br>";              array_push($alltokens,$token);             $this->memcache->set("alltokens",$alltokens);                 echo "addtokenkey 2.2:".count($alltokens)."<br>";         }       }  

i send mulitple request call function @ same time

but sometime same result,ex:

request result

addtokenkey 2.1:5

addtokenkey 2.2:6

another request result

addtokenkey 2.1:5

addtokenkey 2.2:6

how avoid case happen? lock or ..?


refer to:https://github.com/zerkalica/semaphore

i use library try lock & release,the code below:

    function addtokenkey($token)     {        $adapter   = new memcachedadapter($this->memcache);        $semaphore = new semaphoremanager($adapter);           $ttl = 60; // time in seconds, used, if script dies , release never called.        $handle = $semaphore->acquire('addtokenkey_lock_key', $ttl);         $alltokens = $this->memcache->get("alltokens");          if($alltokens == false)         {             //array_push($alltokens,$token);               $array = array();             array_push($array,$token);              $this->memcache->set("alltokens",$array);              echo "addtokenkey 1.2:".count($array)."<br>";         }         else{              echo "addtokenkey 2.1:".count($alltokens)."<br>";              array_push($alltokens,$token);             $result = $this->memcache->set("alltokens",$alltokens);                   echo "addtokenkey 2.2:".count($alltokens)." ".$result."<br>";         }         $semaphore->release($handle);      } 

but got 2 error

fatal error: uncaught exception 'errorexception' message 'can't acquire lock millwright_semaphoreaddtokenkey_lock_key' in /xxxxxxx/server/lib/semaphore/semaphoremanager.php on line 50

fatal error: uncaught exception 'logicexception' message 'call ::acquire('millwright_semaphoremillwright_semaphoreaddtokenkey_lock_key') first' in /xxxxxxx/server/lib/semaphore/semaphoremanager.php on line 65

i fix error in semaphoremanager.php removing "$this->prefix ." code

but still have miss array count problem.

i modify code below try,

i send 100 request,finally alltokens number 50,

others show "unable set"

    function addtokenkey($token)     {                     // initialize lock         $lock = false;         // initialize configurable parameters         $tries = 0;         $max_tries = 1000;         $lock_ttl = 10;          $alltokens = $this->memcache->get("alltokens");          while($lock === false && $tries < $max_tries ) {             if( $alltokens == false ) {                             $alltokens = array();                 array_push($alltokens,$token);                 $this->memcache->set("alltokens",$alltokens);                 echo "addtokenkey 1.2:".count($alltokens)."<br>";                  return;             }              $count = count($alltokens) ;             // add() return false if raced lock             // use add() custom locks             $lock = $this->memcache->add("lock_".$count, 1, $lock_ttl);             $tries++;             usleep(100*($tries%($max_tries/10))); // exponential backoff style of sleep                 }         if($lock === false && $tries >= $max_tries) {                 print("unable set");         } else {                     echo "addtokenkey 2.1:".count($alltokens)."<br>";             array_push($alltokens,$token);             $this->memcache->set("alltokens",$alltokens);                echo "addtokenkey 2.2:".count($alltokens)."<br>";                 }                  } 

finally use memcached getallkeys function fix problem,don't diy record alltokens function can use in linux memcached, windows memcache don't support getallkeys

in normal senario, issue not visible creating problem when there n number of concurrent requests. , because memecache update not atomic normal get/set. use memcached increment/decrement insuring atomicity setting integer valued keys senario there concurrency in requests. since memcached increment() atomic itself, need not put locking mechanism. yes , acheiveing atomicity other race conditions , have apply custom locking etc insure atomicity concurrent requests.

try below , check it:

$mem = new memcache; $mem->addserver("127.0.0.1", 11211);  function incrementuservisits($useridfromrequest) {     global $mem;         $key = "visit_".$useridfromrequest;     $count = $mem->increment($key, 1);     if( $count === false ) {         $count = $mem->add($key, 1, 0, 0);         if($count === false) {                       $count = $mem->increment($key, 1);             if($count === false) {                               return false;             }             else {                               return true;            }        }        else {                       return true;        }    }    else {              return true;    } } incrementuservisits($useridfromrequest); 

you can try below code ( have managed combine/build after bit of research) have not tested syntax error feels in achieving custom lock handle race conditions.

$mem = new memcache; $mem->addserver("127.0.0.1", 11211); function addtokenkey($token) {     global $mem;      // initialize lock     $lock = false;     // initialize configurable parameters     $tries = 0;     $max_tries = 1000;     $lock_ttl = 10;      $alltokens = $mem->get("alltokens");      while($lock === false && $tries < $max_tries ) {         if( gettype($alltokens) == "boolean" ) {                         $alltokens = array();             array_push($alltokens,$token);             $mem->set("alltokens",$alltokens);             echo "addtokenkey 1.2:".count($alltokens)."<br>";                                 }          $count = count($alltokens) ;         // add() return false if raced lock         // use add() custom locks         $lock = $mem->add("lock_".$count, 1, 0, $lock_ttl);         $tries++;         usleep(100*($tries%($max_tries/10))); // exponential backoff style of sleep             }     if($lock === false && $tries >= $max_tries) {             print("unable set");     } else {                 echo "addtokenkey 2.1:".count($alltokens)."<br>";         array_push($alltokens,$token);         $mem->set("alltokens",$alltokens, 0, 0);            echo "addtokenkey 2.2:".count($alltokens)."<br>";             } } addtokenkey('xxx111'); 

apology error think can play , can achieve looking for.


Comments

Popular posts from this blog

java - Plugin org.apache.maven.plugins:maven-install-plugin:2.4 or one of its dependencies could not be resolved -

Round ImageView Android -

How can I utilize Yahoo Weather API in android -