<commit_before>package com.microsoft.applicationinsights.library;

import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;

import com.microsoft.applicationinsights.library.config.ISenderConfig;
import com.microsoft.applicationinsights.logging.InternalLogging;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;

/**
 * This singleton class sends data to the endpoint.
 */
class Sender {

    private static final String TAG = "Sender";

    /**
     * Volatile boolean for double checked synchronize block.
     */
    private static volatile boolean isSenderLoaded = false;


    /**
     * Synchronization LOCK for setting static config.
     */
    private static final Object LOCK = new Object();

    /**
     * The configuration for this sender.
     */
    protected final ISenderConfig config;

    /**
     * The shared Sender instance.
     */
    private static Sender instance;

    private AtomicInteger operationsCount;

    /**
     * Restrict access to the default constructor
     * @param config the telemetryconfig object used to configure the telemetry module
     */
    protected Sender(ISenderConfig config) {
        this.config = config;
    }

    /**
     * Initialize the INSTANCE of sender.
     */
    protected static void initialize(ISenderConfig config) {
        // note: isSenderLoaded must be volatile for the double-checked LOCK to work
        if (!Sender.isSenderLoaded) {
            synchronized (Sender.LOCK) {
                if (!Sender.isSenderLoaded) {
                    Sender.isSenderLoaded = true;
                    Sender.instance = new Sender(config);
                }
            }
        }
    }

    /**
     * @return the INSTANCE of the sender calls initialize before that.
     */
    protected static Sender getInstance() {
        if (Sender.instance == null) {
            InternalLogging.error(TAG, "getInstance was called before initialization");
        }

        return Sender.instance;
    }


    protected void sendDataOnAppStart() {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                sendNextFile();
                return null;
            }
        }.execute();
    }

    protected void sendNextFile(){
        if(runningRequestCount() < 10) {
            // Send the persisted data
            Persistence persistence = Persistence.getInstance();
            if (persistence != null) {
                File fileToSend = persistence.nextAvailableFile();
                if(fileToSend != null) {
                    send(fileToSend);
                }
            }
        }
        else {
            InternalLogging.info(TAG, "We have already 10 pending reguests", "");
        }
    }

    protected void send(File fileToSend) {
        Persistence persistence = Persistence.getInstance();
        String persistedData = persistence.load(fileToSend);
        if (!persistedData.isEmpty()) {
            InternalLogging.info(TAG, "sending persisted data", persistedData);
            try {
                InternalLogging.info(TAG, "sending persisted data", persistedData);
                this.operationsCount.getAndIncrement();
                this.sendRequestWithPayload(persistedData, fileToSend);
            } catch (IOException e) {
                InternalLogging.warn(TAG,"Couldn't send request with IOException: " + e.toString());
            }
        }else{
            persistence.deleteFile(fileToSend);
            sendNextFile();
        }
    }

    protected int runningRequestCount() {
        return this.operationsCount.get();
    }

    protected void sendRequestWithPayload(String payload, File fileToSend) throws IOException {
        Writer writer = null;
        URL url = new URL(config.getEndpointUrl());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setReadTimeout(config.getSenderReadTimeout());
        connection.setConnectTimeout(config.getSenderConnectTimeout());
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");<commit_msg>Fix bug: decrement operation if IOException gets thrown<commit_after>package com.microsoft.applicationinsights.library;

import android.annotation.TargetApi;
import android.os.AsyncTask;
import android.os.Build;

import com.microsoft.applicationinsights.library.config.ISenderConfig;
import com.microsoft.applicationinsights.logging.InternalLogging;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;

/**
 * This singleton class sends data to the endpoint.
 */
class Sender {

    private static final String TAG = "Sender";

    /**
     * Volatile boolean for double checked synchronize block.
     */
    private static volatile boolean isSenderLoaded = false;


    /**
     * Synchronization LOCK for setting static config.
     */
    private static final Object LOCK = new Object();

    /**
     * The configuration for this sender.
     */
    protected final ISenderConfig config;

    /**
     * The shared Sender instance.
     */
    private static Sender instance;

    private AtomicInteger operationsCount;

    /**
     * Restrict access to the default constructor
     * @param config the telemetryconfig object used to configure the telemetry module
     */
    protected Sender(ISenderConfig config) {
        this.config = config;
    }

    /**
     * Initialize the INSTANCE of sender.
     */
    protected static void initialize(ISenderConfig config) {
        // note: isSenderLoaded must be volatile for the double-checked LOCK to work
        if (!Sender.isSenderLoaded) {
            synchronized (Sender.LOCK) {
                if (!Sender.isSenderLoaded) {
                    Sender.isSenderLoaded = true;
                    Sender.instance = new Sender(config);
                }
            }
        }
    }

    /**
     * @return the INSTANCE of the sender calls initialize before that.
     */
    protected static Sender getInstance() {
        if (Sender.instance == null) {
            InternalLogging.error(TAG, "getInstance was called before initialization");
        }

        return Sender.instance;
    }


    protected void sendDataOnAppStart() {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                sendNextFile();
                return null;
            }
        }.execute();
    }

    protected void sendNextFile(){
        if(runningRequestCount() < 10) {
            // Send the persisted data
            Persistence persistence = Persistence.getInstance();
            if (persistence != null) {
                File fileToSend = persistence.nextAvailableFile();
                if(fileToSend != null) {
                    send(fileToSend);
                }
            }
        }
        else {
            InternalLogging.info(TAG, "We have already 10 pending reguests", "");
        }
    }

    protected void send(File fileToSend) {
        Persistence persistence = Persistence.getInstance();
        String persistedData = persistence.load(fileToSend);
        if (!persistedData.isEmpty()) {
            InternalLogging.info(TAG, "sending persisted data", persistedData);
            try {
                InternalLogging.info(TAG, "sending persisted data", persistedData);
                this.operationsCount.getAndIncrement();
                this.sendRequestWithPayload(persistedData, fileToSend);
            } catch (IOException e) {
                InternalLogging.warn(TAG,"Couldn't send request with IOException: " + e.toString());
                this.operationsCount.getAndDecrement();
            }
        }else{
            persistence.deleteFile(fileToSend);
            sendNextFile();
        }
    }

    protected int runningRequestCount() {
        return this.operationsCount.get();
    }

    protected void sendRequestWithPayload(String payload, File fileToSend) throws IOException {
        Writer writer = null;
        URL url = new URL(config.getEndpointUrl());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setReadTimeout(config.getSenderReadTimeout());
        connection.setConnectTimeout(config.getSenderConnectTimeout());
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
{'fraction_non_alphanumeric': 0.0912638196401474, 'fraction_numerical': 0.0008671146759158899, 'mean_word_length': 2.376143432125869, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3146032', 'n_tokens_mistral': 2362, 'n_tokens_neox': 2258, 'n_words': 593}