Set Service's UseFileStream=True, then content is stored on files on server, stream folder of database defined for namespace. 

It doesn't grow then CACHE.DAT anymore, of course it grows still disk usage. But You can add purge task once in day and keep messages for 0 days so everything is cleaned up once in day.

Cleaning grows some journal but not much in this case because file contents are not in CACHE.DAT

And if Your files are so big, that You want use different temporary directory during transfer You can change this for whole system:
^%SYS("TempDir")="/enssys/ensprod/mgr/Temp"

or just for one namespace:
^%SYS("TempDir","YOURNAMESPACE")="/some/temp/dir"

Or build some streaming adapter, it might be good for not so important data, which needed just on demand, not later. Like streaming live video via Ensemble :) 

Eduard's link to InMemory capabilities is interesting, thanks!

Hi!

Have You looked following documentation?

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...

We have made this kind of service class:

Class Istekki.EMail.Service Extends Ens.BusinessService
{

Parameter ADAPTER = "EnsLib.EMail.InboundAdapter";

/// Configuration item(s) to which to send file stream messages
Property TargetConfigNames As %String(MAXLEN = 1000);

Parameter SETTINGS = "TargetConfigNames";

Method OnProcessInput(pInput As %Net.MailMessage, pOutput As %RegisteredObject) As %Status
{

    // Lets trace some
    $$$TRACE("Bcc="_pInput.Bcc)
    $$$TRACE("BinaryData="_pInput.BinaryData)
    $$$TRACE("Cc="_pInput.Cc)
    $$$TRACE("Charset="_pInput.Charset)
    $$$TRACE("ContentTransferEncoding="_pInput.ContentTransferEncoding)
    $$$TRACE("ContentType="_pInput.ContentType)
    $$$TRACE("Date="_pInput.Date)
    $$$TRACE("Dir="_pInput.Dir)
    $$$TRACE("FileName="_pInput.FileName)
    $$$TRACE("From="_pInput.From)
    $$$TRACE("Headers="_pInput.Headers)
    $$$TRACE("InlineAttachment="_pInput.InlineAttachment)
    $$$TRACE("Is7bit="_pInput.Is7bit)
    $$$TRACE("IsAlternative="_pInput.IsAlternative)
    $$$TRACE("IsBase64="_pInput.IsBase64)
    $$$TRACE("IsBinary="_pInput.IsBinary)
    $$$TRACE("IsHTML="_pInput.IsHTML)
    $$$TRACE("IsMultiPart="_pInput.IsMultiPart)
    $$$TRACE("MessageSize="_pInput.MessageSize)
    $$$TRACE("MultiPartType="_pInput.MultiPartType)
    $$$TRACE("Parts="_pInput.Parts)
    $$$TRACE("ReplyTo="_pInput.ReplyTo)
    $$$TRACE("Sender="_pInput.Sender)
    $$$TRACE("Subject="_pInput.Subject)
    $$$TRACE("TextData="_pInput.TextData)
    $$$TRACE("To="_pInput.To)

Set tStatus = $$$OK

    // Check if mail message has multiple parts
    If pInput.IsMultiPart {
        Set tPartsCount = pInput.Parts.Count()
        $$$TRACE("This message has multiple parts; " _ tPartsCount)
        For tInd = 1:1:tPartsCount {
        Set tStatus = ..ProcessPart(pInput.Parts.GetAt(tInd))
        Quit:$$$ISERR(tStatus)
        }
Quit tStatus
    }

// Is not multipart
Set pReq = ##class(Istekki.FTP.Message).%New()
    Set pReq.Source = ..%ConfigName
    If pInput.IsBinary {
     Do pReq.Content.CopyFrom(pInput.BinaryData)
    }
    Else {
     Do pReq.Content.CopyFrom(pInput.TextData)
    }
    Set pReq.SourceFileName = pInput.FileName
For iTarget=1:1:$L(..TargetConfigNames, ",")
Set tOneTarget=$ZStrip($P(..TargetConfigNames,",",iTarget),"<>W")
Continue:""=tOneTarget 
Set tSC1 = ..SendRequestAsync(tOneTarget, pReq)
Set:$$$ISERR(tSC1) tStatus = $$$ADDSC(tStatus,tSC1)
}
$$$TRACE("Attachment processed")
Quit tStatus
}

Method ProcessPart(part As %Net.MailMessagePart) As %Status
{
Set tStatus = $$$OK
If part.FileName '= "" {
     Set pReq = ##class(Istekki.FTP.Message).%New()
        Set pReq.Source = ..%ConfigName
        If part.IsBinary {
         Do pReq.Content.CopyFrom(part.BinaryData)
Else {
         Do pReq.Content.CopyFrom(part.TextData)
        }
Set pReq.SourceFileName = part.FileName
For iTarget=1:1:$L(..TargetConfigNames, ",")
Set tOneTarget=$ZStrip($P(..TargetConfigNames,",",iTarget),"<>W")
Continue:""=tOneTarget 
Set tSC1 = ..SendRequestAsync(tOneTarget, pReq)
Set:$$$ISERR(tSC1) tStatus = $$$ADDSC(tStatus,tSC1)
}
        Quit tStatus
    ElseIf (part.IsMultiPart) {
        Set tPartsCount = part.Parts.Count()
        For tInd = 1:1:tPartsCount {
      Set tStatus = ..ProcessPart(part.Parts.GetAt(tInd))
      Quit:$$$ISERR(tStatus)
        }    
    }
    Quit tStatus
}

/// Return an array of connections for drawing lines on the config diagram
ClassMethod OnGetConnections(Output pArray As %String, pItem As Ens.Config.Item)
{
Do pItem.PopulateModifiedSettings()
Set (tValue,tIndex)="" For {
Set tSetting = pItem.ModifiedSettings.GetNext(.tIndex) Quit:tIndex=""
If tSetting.Name="TargetConfigNames" Set tValue=tSetting.Value  Quit
}
For i=1:1:$L(tValue,",") Set tOne=$ZStrip($P(tValue,",",i),"<>W") Continue:""=tOne  Set pArray(tOne)="" }
}

}

And have it set up in to production like this:

  <Item Name="FromEmail" Category="something" ClassName="Istekki.EMail.Service" PoolSize="1" Enabled="true" Foreground="false" Comment="Receiving attachments in email" LogTraceEvents="true" Schedule="">
    <Setting Target="Host" Name="AlertOnError">1</Setting>
    <Setting Target="Host" Name="TargetConfigNames">toSomeSystem</Setting>
    <Setting Target="Adapter" Name="CallInterval">900</Setting>
    <Setting Target="Adapter" Name="Credentials">SomeCredentials</Setting>
    <Setting Target="Adapter" Name="MatchFrom">Sender@somewhere.fi</Setting>
    <Setting Target="Adapter" Name="MatchSubject">Referral</Setting>
    <Setting Target="Adapter" Name="MatchTo">ensemble@ourdomain.fi</Setting>
    <Setting Target="Adapter" Name="POP3Port">995</Setting>
    <Setting Target="Adapter" Name="POP3Server">mailserver.ourdomain.fi</Setting>
    <Setting Target="Adapter" Name="SSLConfig">POPMAIL</Setting>
    <Setting Target="Host" Name="ThrottleDelay">500</Setting>
    <Setting Target="Host" Name="BusinessPartner">SomePartner</Setting>
  </Item>
 

Best Regards

Mauri

Propably there is no simple answer for this. But ability to easily track and alert connections is many times valuable help. Also sometimes connections are to external servers and we don't want connections from/to internal application servers. Also connections to outside can be two-way-ssl, so this solution needs only one certificate for internal side.

Ensemble environment/configuration needs to be like that it is not point of failure. This can be done with clustering, mirroring or loadbalancer, depending for what Ensemble is depended to use.

Best Regards,

Mauri

Hi!

Just add service (Enslib.HTTP.GenericService) and operation (Enslib.HTTP.GenericOperation) to Your production. WS calls are anyway just http in lower level. If Your operation's URL is left empty, then it uses URL how service is called. So You need only one service/operation for one target server:port in Your production.

But You  need to have quite new Ensemble. With older versions there are some bugs in those adapters, for example getting wsdl through this configuration is not working.

Anyway this is extremely easy to set up and give it a try.

Best Regards

Mauri