Thank you for the explanation. I fixed the code to avoid attempting to copy buffers and to shift state to the ending state in the transform when I get a null return on TSVioBufferGet. But what confuses me is that for larger sized payloads (> 30K) I am getting the TS_EVENT_VCONN_WRITE_COMPLETE before all of the content in the response has been processed. I know this because when I run without the transform, I get back a 35K valid JSON payload from my test URI, but when I apply the transform which does nothing more than inject a short string at the head and the tail of the upstream response, I get truncated json of varying lengths.
Any thoughts on why I might get TS_EVENT_VCONN_WRITE_COMPLETE early. I have verified that my transform is the only transform that can execute. On 3/14/13 2:34 AM, "Uri Shachar" <[email protected]> wrote: >Hi Steve, > > > If the TSVIOBufferGet returns a Null value it means that the write >operation has been shut down for the VIO. >So in your case -- you need to replace the debug msg with some plugin >logic (what exactly the plugin should do in this case depends on what you >are trying to achieve) . > >You can see how the sample plugins handle this situation by grepping >through the example/ plugins -- for example -- in the server-transform >plugin: > > /* We also check to see if the write VIO's buffer is non-NULL. A > NULL buffer indicates that the write operation has been > shutdown and that the continuation does not want us to send any > more WRITE_READY or WRITE_COMPLETE events. For this buffered > transformation that means we're done buffering data. */ >.... > > Cheers, > Uri > > >________________________________ >> From: [email protected] >> To: [email protected] >> Date: Wed, 13 Mar 2013 16:22:54 -0700 >> Subject: Question about sanity check >> >> I have a transformation plugin which contains a block of code as shown >> below (Exhibit A). The code is dying with an error showing up in the >> traffic server logs as shown in exhibit B. As near as I can tell from >> reading the code in line 538 of InkIOCoreAPI.cc. the assertion is >> testing to see if the bufp pointer passed in is null. >> >> My question is under what conditions might this pointer be null. The >> behavior I am seeing is that the transform returns the first part of >> the content, but then dies. Presumably because some state is not >> correct. But I don't understand what could be going wrong. >> >> I noticed that the same stack trace also appears >> in https://issues.apache.org/jira/browse/TS-1517. >> >> So I don't know if this is a bug in ATS or if this is a problem in the >> way I am using the API. >> >> Any thoughts? >> >> ------------ Exhibit A ------------------------- >> /* Determine how much data we have left to read. For this null >> * transform plugin this is also the amount of data we have >>left >> * to write to the output connection. >> */ >> int64_t upstream_todo = TSVIONTodoGet(input_vio); >> if (upstream_todo > 0) { >> /* The amount of data left to read needs to be >>truncated by >> * the amount of data actually in the read buffer. >> */ >> int64_t upstream_avail = TSIOBufferReaderAvail( >> TSVIOReaderGet(input_vio)); >> int64_t towrite = upstream_todo; >> if (towrite > upstream_avail) { >> towrite = upstream_avail; >> } >> >> >> if (towrite > 0) { >> TSIOBufferReader readerp = >>TSVIOReaderGet(input_vio); >> TSIOBuffer bufp = >>TSVIOBufferGet(data->output_vio); >> if(readerp == NULL || bufp == NULL) { >> TSDebug(DEBUG_NAME, >> "Danger Will Robinson! We are probably >> >> going to crash because readerp = %d and bufp = %d" >> " and towrite = %d and upstream_todo = >> >> %d and upstream_avail = %d", >> readerp, bufp, towrite); >> } >> >> /* Copy the data from the read buffer to the >> output buffer. */ >> bytesWritten += TSIOBufferCopy(bufp, readerp, >> towrite, 0); >> >> /* Tell the read buffer that we have read >> 'towrite' bytes of data >> * and are no longer interested in it. >> */ >> TSIOBufferReaderConsume(readerp, >>bytesWritten); >> >> /* Increment the input VIO nDone value to >> reflect how much >> * data we've copied from the upstream and >> written to the >> * downstream. >> */ >> TSVIONDoneSet(input_vio, >> TSVIONDoneGet(input_vio) + bytesWritten); >> } >> } >> ------------------------ End of Exhibit A --------------------------- >> >> ----------------- Exhibit B ------------------------------- >> [Mar 13 16:12:32.579] Server {0x421fa940} DIAG: >> (ApiMgmtPlugin.AssertionHandler.DEBUG) Executing >> FATAL: InkIOCoreAPI.cc:538: failed assert >> `sdk_sanity_check_iocore_structure(bufp) == TS_SUCCESS` >> /usr/local/bin/traffic_server - STACK TRACE: >> /usr/local/lib/libtsutil.so.3(ink_fatal+0x88)[0x2afc06ace7a8] >> /usr/local/lib/libtsutil.so.3(_ink_assert+0x1f)[0x2afc06accf6f] >> /usr/local/bin/traffic_server(_TSReleaseAssert+0x9)[0x49b3f9] >> /usr/local/bin/traffic_server(TSIOBufferCopy+0xa1)[0x4b7a71] >> >>/usr/local/lib/trafficserver/plugins/libJsonPTransformationHandlerPlugin. >>so(_ZN11apim_plugin26JsonPTransformationHandler30handleMiddleTransformOpe >>rationEPNS_18TransformationDataEP9tsapi_vio+0xfe)[0x2aaab44458d8] >> >>/usr/local/lib/trafficserver/plugins/libJsonPTransformationHandlerPlugin. >>so(_ZN11apim_plugin26JsonPTransformationHandler24handleTransformOperation >>EP10tsapi_cont+0x1da)[0x2aaab4445b08] >> >>/usr/local/lib/trafficserver/plugins/libJsonPTransformationHandlerPlugin. >>so(_ZN11apim_plugin26JsonPTransformationHandler15callbackHandlerEP10tsapi >>_cont7TSEventPv+0x12c)[0x2aaab4445dcc] >> >>/usr/local/bin/traffic_server(_ZN7EThread13process_eventEP5Eventi+0x22f)[ >>0x6b9c0f] >> /usr/local/bin/traffic_server(_ZN7EThread7executeEv+0x1aa)[0x6ba10a] >> /usr/local/bin/traffic_server[0x6b905e] >> /lib64/libpthread.so.0[0x337140677d] >> /lib64/libc.so.6(clone+0x6d)[0x3370cd3c1d] >> ----------------- End of Exhibit B >>------------------------------------- >>
