A quick question, I'm venturing into Kafka using php-rdkafka ( https://github.com/arnaud-lb/php-rdkafka ).
I went through the documentation and i can't find the syntax to produce into existing topic unless the syntax newTopic will insert to the existing topic which i doubt. I keep on getting Java error thrown and i'm not good debugging Java error. I'm seeking help from those who has been using the framework , is it a correct syntax? Please advice
<?php
$conf = new RdKafka\Conf();
$conf->set('metadata.broker.list', 'localhost:9092');
//If you need to produce exactly once and want to keep the original produce order, uncomment the line below
//$conf->set('enable.idempotence', 'true');
$producer = new RdKafka\Producer($conf);
$topic = $producer->newTopic("test"); // Is this a correct syntax to consume existing topic?
for ($i = 0; $i < 10; $i++) {
$topic->produce(RD_KAFKA_PARTITION_UA, 0, "Message $i");
$producer->poll(0);
}
for ($flushRetries = 0; $flushRetries < 10; $flushRetries++) {
$result = $producer->flush(10000);
if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) {
break;
}
}
if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) {
throw new \RuntimeException('Was unable to flush, messages might be lost!');
}
As per discussion with the developer,
The following syntax can be used to create new topic and add the data to the following/existing topic
$topic = $producer->newTopic("test"); /
Related
I am building a simple auction solution on Laravel. The below code is some extract test code that is suppose to act as the auctioneer.
The problem is that when it's running it locks up access to the Auctionbid Postgres table and users can't bid while it's running. My testing is on localhost running a few users in auction as well as the auctioneer process all on same box/same IP<--might be making issue worse (not sure).
I've read all about the issues on SO about sleep(), downsides of polling and PHP sessions and have dug into Websockets a bit to see if I should go there. It also would also allow me to replace Pusher.
However, the issue I see is that an auction is all about timing and what events are NOT happening (if no bid in 3 seconds tell users "Fair Warning") and the Websocket implementations I've read about seem to be about what events ARE happening.
Questions:
Would a websockets implementation possibly be a solution? Every article I've looked at seems to be about the events that ARE happening. Maybe the classes on negative space are hindering my ability to see the solution :-)
Is having this all run on the same box/IP the issue? And/Or is sleep() just a bad way moving forward - as pointed out in at least 100 SO posts...
What are other possible solutions that allow me to check for what events are NOT happening?
public function RunTheAuction($auction_item_id, $auction_id)
{
set_time_limit(300);
$options = array(
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true
);
$pusher = new Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
$options
);
$bidIncrementResetCounter = 0;
$lastBidderId = 0;
$currentWinnerBidAmount = 0;
$lastBidderBidAmount = 0;
$count = 0;
while(true){
$auctionbid = Auctionbid::select('id', 'bid', 'bid_timestamp', 'auction_bidder_id')
->where('auction_item_id', '=', $auction_item_id)
->where('auction_id', '=', $auction_id)
->orderBy('bid', 'desc')
->orderBy('bid_timestamp', 'asc')
->first();
if ($auctionbid) { //there is a bid on the item
$currentWinnerId = $auctionbid->id;
$currentWinnerBidAmount = $auctionbid->bid;
if (($lastBidderId == $currentWinnerId) && ($lastBidderBidAmount == $currentWinnerBidAmount)) { //it's the same bidder
if ($bidIncrementResetCounter == 1) {
$message = "Fair Warning!";
$pusher->trigger('bids_channel', 'bid-warning', $message);
}
if ($bidIncrementResetCounter == 2) {
$message = "Going once... Going twice...";
$pusher->trigger('bids_channel', 'bid-warning', $message);
}
if ($bidIncrementResetCounter == 3) {
$message = "We have a winner!";
$pusher->trigger('bids_channel', 'bid-warning', $message);
break;
}
$bidIncrementResetCounter++;
} else {
$bidIncrementResetCounter = 0;
}
}
else{
$currentWinnerId = 0;
}
$lastBidderId = $currentWinnerId;
$lastBidderBidAmount = $currentWinnerBidAmount;
sleep(10); //<-----------------------------ISSUE
$count++;
if($count == 12){break;}
} //end loop
} //end function RunTheAuction
I'm having this error "Property Order->id_customer is empty" occur only when orders are inputted and submitted via the Selenium chromedriver. I'm running PrestaShop 1.6 and I do not get this error when I enter the same order details manually.
I don't think it's an issue with the actual selenium script, but possibly with the webdriver; I thought it could due to missing data in a cookie or not actually selecting fields but when I inspected the packet from the form submission nothing was missing when compared to the manual entry.
I've also emptied the prestashop cache and deleted all the browser data from chrome in case it was due to cached data but no such luck.
I did override multiple files related to the order submission to accommodate some project requirements, specifically PaymentModule, Order, & AdminOrdersController but I don't know how that could be the issue if the manual entry works fine. I've been debugging anyway since I've been grasping for ideas and so in case it's actually due to my override I've been trying to debug variables in them but keep running into issues; I can't actually output the variables, I tried looking at PrestaShop Logs (Dev_mode is on), echoing, var_dumping, using PrestaShop's p(), and saving to file but no data comes out.
I could really use a direct solution but I at least need some new ideas for debugging.
EDIT: Here are the overridden files.
PaymentModules.php:
$order_list = array();
$order_detail_list = array();
do {
//changed from generateReference()
$reference = Order::generateReferenceOrderID($extra_vars[0]);
} while (Order::getByReference($reference)->count());
$this->currentOrderReference = $reference;
Order.php:
Class Order extends OrderCore
{
//needed to abide by project requirements prefix system.
public static function generateReference(){
$id_shop = Context::getContext()->shop->id;
$ref_store = "ABCD";
if($id_shop == 1){
$ref_store = "TCPR";
}
else if ($id_shop == 2){
$ref_store = "LOER";
}
else if ($id_shop == 3){
$ref_store = "TCPW";
}
$AUTO_INCREMENT = Db::getInstance()->getValue("
SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'ts'
AND TABLE_NAME = 'orders'");
$last_id = Db::getInstance()->getValue("
SELECT MAX(id_order)
FROM '._DB_PREFIX_.'orders");
if($last_id < $AUTO_INCREMENT){
$last_id = $AUTO_INCREMENT - 1;
}
$result = $ref_store . str_pad((int)$last_id + 1, 5, '00000', STR_PAD_LEFT);
return $result;
}
public static function generateReferenceOrderID($order_id){
$ref_store = "SQSP";
$result = $ref_store . str_pad((int)$order_id, 5, '00000', STR_PAD_LEFT);
return $result;
}
}
AdminOrdersController.php:
$employee = new Employee((int)Context::getContext()->cookie->id_employee);
//passing order message into extra_vars for use in PaymentModule
$payment_module->validateOrder(
(int)$cart->id, (int)$id_order_state,
$cart->getOrderTotal(true, Cart::BOTH),
$payment_module->displayName,
$this->l('Manual order -- Employee:').' '.
substr($employee->firstname, 0, 1).'. '.$employee->lastname,
array(Tools::getValue('order_message')), null, false,
$cart->secure_key);
Is there anybody who knows how to get whole LDAP error codes?
I'm using in PHP ldap_error($ldapConn) for code and ldap_errno($ldapConn) for name of the error. But error 49 - LDAP_INVALID_CREDENTIALS has 'suberrors' like 49/525, 49/530 etc. I need whole number of error but ldap_error() shows only 49 for example.
You can do something like this:
ldap_get_option($ldapConn, LDAP_OPT_ERROR_STRING, $diagnosticMsg);
echo $diagnosticMsg;
Where $diagnosticMsg is then the full message that contains the extra information you're looking for.
In newer versions of PHP you can use LDAP_OPT_DIAGNOSTIC_MESSAGE instead. That will contain the extended error code you're looking for. You can parse it doing something like this:
function getExtendedErrorNumber($diagnosticMsg) {
$errorNumber = 0;
if (!empty($diagnosticMsg)) {
$errorNumber = explode(',', $diagnosticMsg);
if (!isset($errorNumber[2])) {
return 0;
};
$errorNumber = explode(' ', $errorNumber[2]);
if (!isset($errorNumber[2])) {
return 0;
};
$errorNumber = hexdec(intval($errorNumber[2]));
}
return $errorNumber;
}
Subject is quite self-explanatory, but I definitely need a fresh pair of eyes on this.
I am using mmoreram/GearmanBundle Symfony2 bundle to send jobs to execute. So, far I have managed to send a job, execute it and return results. That part works as expected.
However, I am trying to the same with background job/tasks. I know that, in this scenario, client does not wait for job to complete, but I was hoping that job handle can help me with that (e.g. retrieve job status).
$gearman = $this->get('gearman');
$jobId = $gearman->doHighBackgroundJob("CsvWorker~parseCsv", json_encode(["foo", "bar", "123"]));
sleep(3);
// At this point, job has completed for sure (it's very simple)
var_dump($jobId);
var_dump($gearman->getJobStatus($jobId));
This outputs the following:
string 'H:localhost.localdomain:10' (length=26)
object(Mmoreram\GearmanBundle\Module\JobStatus)[410]
private 'known' => boolean false
private 'running' => boolean false
private 'completed' => int 0
private 'completionTotal' => int 0
The known => false, in particular, really puzzles me. During the job execution, I made sure to invoke correctly sendStatus and sendComplete methods.
So, I guess, a general question would be: once the job has completed, is it still known to Gearman?
UPDATE:
I managed to add some code changes to the bundle which allowed me to listen for data being returned by job. That way, I may be able to persist that in database, however, my client (job creator) is still pretty much left in the dark on whether the job has actually finished.
I found here such an option for solving the problem.
It is convenient when you need to complete a task, and the answer is needed only for a while.
Worker
$gmworker = new GearmanWorker();
$gmworker->addServer();
$gmworker->addFunction("long_running_task", "long_running_task_fn");
print "Waiting for job...\n";
while($gmworker->work()) {
if ($gmworker->returnCode() != GEARMAN_SUCCESS) {
echo "return_code: " . $gmworker->returnCode() . "\n";
break;
}
}
function long_running_task_fn($job) {
$mc = memcache_connect('localhost', 11211);
$result = 1;
$n = $job->workload();
for ($i = 1; $i <= $n; $i++) {
$result *= $i;
$job->sendStatus($i, $n);
sleep(1);
}
memcache_set($mc, $job->handle(), $result);
}
Client
<?php
if ($_POST['start']) {
$gmc = new GearmanClient();
$gmc->addServer();
$handle = $gmc->doBackground('long_running_task', '10');
header('Location: /client.php?handle='.urlencode($handle));
}
if ($_GET['handle']) {
$handle = $_GET['handle'];
$gmc = new GearmanClient();
$gmc->addServer();
$status = $gmc->jobStatus($handle);
}
function get_result($handle) {
$mc = memcache_connect('localhost', 11211);
$reply = memcache_get($mc, $handle);
memcache_close($mc);
return $reply;
}
?>
As described in PHP Manual, as long as the job is known to the server, it is not completed.
I don't know how to make this.
There is an XML Api server and I'm getting contents with cURL; it works fine. Now I have to call the creditCardPreprocessors state. It has 'in progress state' too and PHP should wait until the progess is finished. I tried already with sleep and other ways, but I can't make it. This is a simplified example variation of what I tried:
function process_state($xml){
if($result = request($xml)){
// It'll return NULL on bad state for example
return $result;
}
sleep(3);
process_state($xml);
}
I know, this can be an infite loop but I've tried to add counting to exit if it reaches five; it won't exit, the server will hang up and I'll have 500 errors for minutes and Apache goes unreachable for that vhost.
EDIT:
Another example
$i = 0;
$card_state = false;
// We're gona assume now the request() turns back NULL if card state is processing TRUE if it's done
while(!$card_state && $i < 10){
$i++;
if($result = request('XML STUFF')){
$card_state = $result;
break;
}
sleep(2);
}
The recursive method you've defined could cause problems depending on the response timing you get back from the server. I think you'd want to use a while loop here. It keeps the requests serialized.
$returnable_responses = array('code1','code2','code3'); // the array of responses that you want the function to stop after receiving
$max_number_of_calls = 5; // or some number
$iterator = 0;
$result = NULL;
while(!in_array($result,$returnable_responses) && ($iterator < $max_number_of_calls)) {
$result = request($xml);
$iterator++;
}