RTC Forums
November 24, 2024, 08:48:43 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: RtcFunction result from FromJSON  (Read 5469 times)
Theprasit
RTC License++
*****
Posts: 42


« on: January 14, 2015, 03:53:42 PM »

Hi Danijel,

I need to return a result as TRtcRecord to use with RtcScript. The return result was create using TRtcRecord.FromJSON(). The function return is ok but I got memory leak from FastMM4. Following is my code:-

Code:
procedure TrfCbtComm.ExecGetPlantInfo(Sender: TRtcConnection; Param: TRtcFunctionInfo; Result: TRtcValue);
const
  SQL1= 'select UBLOB from T00010 where UID=:UID';
var
  uni_conn: TUniConnEx;
  s_st: TStringStream;
  j_son: string;
  uid: Integer;
begin
  if not Param.CheckType('PlantID', rtc_Text) then RaiseException('PlantID parameter is required')
  else begin
    s_st:= TStringStream.Create;
    uni_conn:= RDM.GetUniConn(GetConnID(Param));
    try
      try
        uid:= 120+ StrToIntDef(Copy(Param.asText['Plant_ID'], 4, 1), 1);
        uni_conn.Q10.OpenX(SQL1, [uid]);
        if uni_conn.Q10.IsEmpty then RaiseException('Error> GetPlantInfo> PlantID is not found')
        else begin
          (uni_conn.Q10.Fields[0] as TBlobField).SaveToStream(s_st);
          j_son:= s_st.DataString;
          j_son:= StringReplace(j_son, #13#10, '', [rfReplaceAll]);
          j_son:= StringReplace(j_son, #09, '', [rfReplaceAll]);

          Result.isNull:= True;
          Result.asRecord:= TRtcRecord.FromJSON(j_son);

        end;
      except
        on E: Exception do RaiseException('GetPlantInfo', E.Message);
      end;
    finally
      s_st.Free;
      RDM.PutUniConn(uni_conn);
    end;
  end;
end;

I tried several coding using copyOf or .asObject but not success. Do you have any advises?

Regards,

Theprasit
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: January 14, 2015, 06:26:42 PM »

Using "asJSON", you can simply assign the JSON String to the result, like this:

Result.asJSON := j_son;

Alternatively, if you KNOW that your JSON String contains a record, you can do this:

Result.asObject := TRtcRecord.FromJSON(j_son);

Best Regards,
Danijel Tkalcec
Logged
Theprasit
RTC License++
*****
Posts: 42


« Reply #2 on: January 15, 2015, 09:51:56 AM »

Hi Danijel,

Sorry for late response, have to do testing in several cases.

Per your answer, I resolved the issue about return result from TRtcRecord.FromJSON but a memory leak still there. After do more debugging, I found a cause that came from RtcScriptEngine. (I use RtcDataProvider to call script that call RtcFunction, so debugging is a bit difficult).

When using RtcScriptEngine.Execute, I used a global VAR of TRtcValue to receive a result return from script engine, now I realize that return result from RtcScriptEngine is seem like return result from RTCFunction, mean RTC will create not me, so I changed the code as in the following and the memory leak is gone.

Code:
  TqslHtmlCommandDispatcher = class(TComponent)
  private
    FScriptResult: TRtcValue;
  .. .

procedure TqslHtmlCommandDispatcher.ExecScript(const aScript: string);
begin
  FreeAndNil(FScriptResult);
  FScriptResult:= FScriptEngine.Execute(FDataServer, FScriptEngine.Compile(aScript));
end;

As per this issue, could you clarify me about these questions:-

1. TRtcRecord.FromJSON(j_son) is a class method, that will create an instance when use. If we already have an instance, we have to use .asJSON instead?

2. If we use global var to received return result from RtcScriptEngine, we need to free it before next received. I tried using FScriptResult:= nil; is not enough, still got memory leak.

Thank you for your great product and support

Best Regards,

Theprasit



Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: January 15, 2015, 09:02:17 PM »

1. TRtcRecord.FromJSON class method will create a new TRtcRecord instance, but using "asRecord" to assign an instance will create a copy and assign that copy (not the original), which is why using "asRecord" to assign an instance created with TRtcRecord.FromJSON generates a memory leak. Using "asObject" to assign an instance created with "TRecord.FromJSON" does not generate a memory leak because the original instance will be assigned. But if you have a JSON String, instead of creating an instance of TRtcRecord using "TRtcRecord.FromJSON" and assigning that instance with "asObject", you can simply assign the JSON String with "asJSON".

2. RtcScriptEngine.Compile creates an instance of TRtcValue, which can be passed over to RtcScriptEngine.Execute for execution. In this execution process, the compiled script object will be destroyed by the execution engine, generating a new TRtcValue instance containing the result. Naturally, if you do not need the result, you should free the object returned. But, I do not recommend using a global variable nor a private object member to store the result of the Script Execute method. I would use a local variable instead and Free it immediately after the execution, like this:

procedure TqslHtmlCommandDispatcher.ExecScript(const aScript: string);
  var
    FScriptResult: TRtcValue;
  begin
  FScriptResult:= FScriptEngine.Execute(FDataServer, FScriptEngine.Compile(aScript));
  FreeAndNil(FScriptResult);
  end;

If you need the result (normally the result would be a new string), you could change the procedure into a function, like this:

function TqslHtmlCommandDispatcher.ExecScript(const aScript: string):string;
  var
    FScriptResult: TRtcValue;
  begin
  FScriptResult:=FScriptEngine.Execute(FDataServer, FScriptEngine.Compile(aScript));
  Result:=FScriptResult.asText;
  FreeAndNil(FScriptResult);
  end;

Best Regards,
Danijel Tkalcec
Logged
Theprasit
RTC License++
*****
Posts: 42


« Reply #4 on: January 18, 2015, 12:50:36 PM »

Hi Danijel,

Thank you for your clarified answer, I aware of using global var and will changed code according to your advice.

Thank you and Best Regards,

Theprasit
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.026 seconds with 17 queries.